//===--- ExprClassification.cpp - Expression AST Node Implementation ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Expr::classify.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;

typedef Expr::Classification Cl;

static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E);
static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D);
static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T);
static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E);
static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E);
static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
                                     const Expr *trueExpr,
                                     const Expr *falseExpr);
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
                                       Cl::Kinds Kind, SourceLocation &Loc);

Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
  assert(!TR->isReferenceType() && "Expressions can't have reference type.");

  Cl::Kinds kind = ClassifyInternal(Ctx, this);
  // C99 6.3.2.1: An lvalue is an expression with an object type or an
  //   incomplete type other than void.
  if (!Ctx.getLangOpts().CPlusPlus) {
    // Thus, no functions.
    if (TR->isFunctionType() || TR == Ctx.OverloadTy)
      kind = Cl::CL_Function;
    // No void either, but qualified void is OK because it is "other than void".
    // Void "lvalues" are classified as addressable void values, which are void
    // expressions whose address can be taken.
    else if (TR->isVoidType() && !TR.hasQualifiers())
      kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void);
  }

  // Enable this assertion for testing.
  switch (kind) {
  case Cl::CL_LValue: assert(getValueKind() == VK_LValue); break;
  case Cl::CL_XValue: assert(getValueKind() == VK_XValue); break;
  case Cl::CL_Function:
  case Cl::CL_Void:
  case Cl::CL_AddressableVoid:
  case Cl::CL_DuplicateVectorComponents:
  case Cl::CL_MemberFunction:
  case Cl::CL_SubObjCPropertySetting:
  case Cl::CL_ClassTemporary:
  case Cl::CL_ArrayTemporary:
  case Cl::CL_ObjCMessageRValue:
  case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break;
  }

  Cl::ModifiableType modifiable = Cl::CM_Untested;
  if (Loc)
    modifiable = IsModifiable(Ctx, this, kind, *Loc);
  return Classification(kind, modifiable);
}

/// Classify an expression which creates a temporary, based on its type.
static Cl::Kinds ClassifyTemporary(QualType T) {
  if (T->isRecordType())
    return Cl::CL_ClassTemporary;
  if (T->isArrayType())
    return Cl::CL_ArrayTemporary;

  // No special classification: these don't behave differently from normal
  // prvalues.
  return Cl::CL_PRValue;
}

static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang,
                                       const Expr *E,
                                       ExprValueKind Kind) {
  switch (Kind) {
  case VK_RValue:
    return Lang.CPlusPlus ? ClassifyTemporary(E->getType()) : Cl::CL_PRValue;
  case VK_LValue:
    return Cl::CL_LValue;
  case VK_XValue:
    return Cl::CL_XValue;
  }
  llvm_unreachable("Invalid value category of implicit cast.");
}

static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
  // This function takes the first stab at classifying expressions.
  const LangOptions &Lang = Ctx.getLangOpts();

  switch (E->getStmtClass()) {
  case Stmt::NoStmtClass:
#define ABSTRACT_STMT(Kind)
#define STMT(Kind, Base) case Expr::Kind##Class:
#define EXPR(Kind, Base)
#include "clang/AST/StmtNodes.inc"
    llvm_unreachable("cannot classify a statement");

    // First come the expressions that are always lvalues, unconditionally.
  case Expr::ObjCIsaExprClass:
    // C++ [expr.prim.general]p1: A string literal is an lvalue.
  case Expr::StringLiteralClass:
    // @encode is equivalent to its string
  case Expr::ObjCEncodeExprClass:
    // __func__ and friends are too.
  case Expr::PredefinedExprClass:
    // Property references are lvalues
  case Expr::ObjCSubscriptRefExprClass:
  case Expr::ObjCPropertyRefExprClass:
    // C++ [expr.typeid]p1: The result of a typeid expression is an lvalue of...
  case Expr::CXXTypeidExprClass:
    // Unresolved lookups get classified as lvalues.
    // FIXME: Is this wise? Should they get their own kind?
  case Expr::UnresolvedLookupExprClass:
  case Expr::UnresolvedMemberExprClass:
  case Expr::CXXDependentScopeMemberExprClass:
  case Expr::DependentScopeDeclRefExprClass:
    // ObjC instance variables are lvalues
    // FIXME: ObjC++0x might have different rules
  case Expr::ObjCIvarRefExprClass:
  case Expr::FunctionParmPackExprClass:
    return Cl::CL_LValue;

    // C99 6.5.2.5p5 says that compound literals are lvalues.
    // In C++, they're prvalue temporaries.
  case Expr::CompoundLiteralExprClass:
    return Ctx.getLangOpts().CPlusPlus ? ClassifyTemporary(E->getType())
                                       : Cl::CL_LValue;

    // Expressions that are prvalues.
  case Expr::CXXBoolLiteralExprClass:
  case Expr::CXXPseudoDestructorExprClass:
  case Expr::UnaryExprOrTypeTraitExprClass:
  case Expr::CXXNewExprClass:
  case Expr::CXXThisExprClass:
  case Expr::CXXNullPtrLiteralExprClass:
  case Expr::ImaginaryLiteralClass:
  case Expr::GNUNullExprClass:
  case Expr::OffsetOfExprClass:
  case Expr::CXXThrowExprClass:
  case Expr::ShuffleVectorExprClass:
  case Expr::IntegerLiteralClass:
  case Expr::CharacterLiteralClass:
  case Expr::AddrLabelExprClass:
  case Expr::CXXDeleteExprClass:
  case Expr::ImplicitValueInitExprClass:
  case Expr::BlockExprClass:
  case Expr::FloatingLiteralClass:
  case Expr::CXXNoexceptExprClass:
  case Expr::CXXScalarValueInitExprClass:
  case Expr::UnaryTypeTraitExprClass:
  case Expr::BinaryTypeTraitExprClass:
  case Expr::TypeTraitExprClass:
  case Expr::ArrayTypeTraitExprClass:
  case Expr::ExpressionTraitExprClass:
  case Expr::ObjCSelectorExprClass:
  case Expr::ObjCProtocolExprClass:
  case Expr::ObjCStringLiteralClass:
  case Expr::ObjCBoxedExprClass:
  case Expr::ObjCArrayLiteralClass:
  case Expr::ObjCDictionaryLiteralClass:
  case Expr::ObjCBoolLiteralExprClass:
  case Expr::ParenListExprClass:
  case Expr::SizeOfPackExprClass:
  case Expr::SubstNonTypeTemplateParmPackExprClass:
  case Expr::AsTypeExprClass:
  case Expr::ObjCIndirectCopyRestoreExprClass:
  case Expr::AtomicExprClass:
    return Cl::CL_PRValue;

    // Next come the complicated cases.
  case Expr::SubstNonTypeTemplateParmExprClass:
    return ClassifyInternal(Ctx,
                 cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());

    // C++ [expr.sub]p1: The result is an lvalue of type "T".
    // However, subscripting vector types is more like member access.
  case Expr::ArraySubscriptExprClass:
    if (cast<ArraySubscriptExpr>(E)->getBase()->getType()->isVectorType())
      return ClassifyInternal(Ctx, cast<ArraySubscriptExpr>(E)->getBase());
    return Cl::CL_LValue;

    // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a
    //   function or variable and a prvalue otherwise.
  case Expr::DeclRefExprClass:
    if (E->getType() == Ctx.UnknownAnyTy)
      return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
               ? Cl::CL_PRValue : Cl::CL_LValue;
    return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());

    // Member access is complex.
  case Expr::MemberExprClass:
    return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E));

  case Expr::UnaryOperatorClass:
    switch (cast<UnaryOperator>(E)->getOpcode()) {
      // C++ [expr.unary.op]p1: The unary * operator performs indirection:
      //   [...] the result is an lvalue referring to the object or function
      //   to which the expression points.
    case UO_Deref:
      return Cl::CL_LValue;

      // GNU extensions, simply look through them.
    case UO_Extension:
      return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());

    // Treat _Real and _Imag basically as if they were member
    // expressions:  l-value only if the operand is a true l-value.
    case UO_Real:
    case UO_Imag: {
      const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
      Cl::Kinds K = ClassifyInternal(Ctx, Op);
      if (K != Cl::CL_LValue) return K;

      if (isa<ObjCPropertyRefExpr>(Op))
        return Cl::CL_SubObjCPropertySetting;
      return Cl::CL_LValue;
    }

      // C++ [expr.pre.incr]p1: The result is the updated operand; it is an
      //   lvalue, [...]
      // Not so in C.
    case UO_PreInc:
    case UO_PreDec:
      return Lang.CPlusPlus ? Cl::CL_LValue : Cl::CL_PRValue;

    default:
      return Cl::CL_PRValue;
    }

  case Expr::OpaqueValueExprClass:
    return ClassifyExprValueKind(Lang, E, E->getValueKind());

    // Pseudo-object expressions can produce l-values with reference magic.
  case Expr::PseudoObjectExprClass:
    return ClassifyExprValueKind(Lang, E,
                                 cast<PseudoObjectExpr>(E)->getValueKind());

    // Implicit casts are lvalues if they're lvalue casts. Other than that, we
    // only specifically record class temporaries.
  case Expr::ImplicitCastExprClass:
    return ClassifyExprValueKind(Lang, E, E->getValueKind());

    // C++ [expr.prim.general]p4: The presence of parentheses does not affect
    //   whether the expression is an lvalue.
  case Expr::ParenExprClass:
    return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr());

    // C11 6.5.1.1p4: [A generic selection] is an lvalue, a function designator,
    // or a void expression if its result expression is, respectively, an
    // lvalue, a function designator, or a void expression.
  case Expr::GenericSelectionExprClass:
    if (cast<GenericSelectionExpr>(E)->isResultDependent())
      return Cl::CL_PRValue;
    return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr());

  case Expr::BinaryOperatorClass:
  case Expr::CompoundAssignOperatorClass:
    // C doesn't have any binary expressions that are lvalues.
    if (Lang.CPlusPlus)
      return ClassifyBinaryOp(Ctx, cast<BinaryOperator>(E));
    return Cl::CL_PRValue;

  case Expr::CallExprClass:
  case Expr::CXXOperatorCallExprClass:
  case Expr::CXXMemberCallExprClass:
  case Expr::UserDefinedLiteralClass:
  case Expr::CUDAKernelCallExprClass:
    return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType());

    // __builtin_choose_expr is equivalent to the chosen expression.
  case Expr::ChooseExprClass:
    return ClassifyInternal(Ctx, cast<ChooseExpr>(E)->getChosenSubExpr(Ctx));

    // Extended vector element access is an lvalue unless there are duplicates
    // in the shuffle expression.
  case Expr::ExtVectorElementExprClass:
    return cast<ExtVectorElementExpr>(E)->containsDuplicateElements() ?
      Cl::CL_DuplicateVectorComponents : Cl::CL_LValue;

    // Simply look at the actual default argument.
  case Expr::CXXDefaultArgExprClass:
    return ClassifyInternal(Ctx, cast<CXXDefaultArgExpr>(E)->getExpr());

    // Same idea for temporary binding.
  case Expr::CXXBindTemporaryExprClass:
    return ClassifyInternal(Ctx, cast<CXXBindTemporaryExpr>(E)->getSubExpr());

    // And the cleanups guard.
  case Expr::ExprWithCleanupsClass:
    return ClassifyInternal(Ctx, cast<ExprWithCleanups>(E)->getSubExpr());

    // Casts depend completely on the target type. All casts work the same.
  case Expr::CStyleCastExprClass:
  case Expr::CXXFunctionalCastExprClass:
  case Expr::CXXStaticCastExprClass:
  case Expr::CXXDynamicCastExprClass:
  case Expr::CXXReinterpretCastExprClass:
  case Expr::CXXConstCastExprClass:
  case Expr::ObjCBridgedCastExprClass:
    // Only in C++ can casts be interesting at all.
    if (!Lang.CPlusPlus) return Cl::CL_PRValue;
    return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());

  case Expr::CXXUnresolvedConstructExprClass:
    return ClassifyUnnamed(Ctx, 
                      cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
      
  case Expr::BinaryConditionalOperatorClass: {
    if (!Lang.CPlusPlus) return Cl::CL_PRValue;
    const BinaryConditionalOperator *co = cast<BinaryConditionalOperator>(E);
    return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
  }

  case Expr::ConditionalOperatorClass: {
    // Once again, only C++ is interesting.
    if (!Lang.CPlusPlus) return Cl::CL_PRValue;
    const ConditionalOperator *co = cast<ConditionalOperator>(E);
    return ClassifyConditional(Ctx, co->getTrueExpr(), co->getFalseExpr());
  }

    // ObjC message sends are effectively function calls, if the target function
    // is known.
  case Expr::ObjCMessageExprClass:
    if (const ObjCMethodDecl *Method =
          cast<ObjCMessageExpr>(E)->getMethodDecl()) {
      Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getResultType());
      return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
    }
    return Cl::CL_PRValue;
      
    // Some C++ expressions are always class temporaries.
  case Expr::CXXConstructExprClass:
  case Expr::CXXTemporaryObjectExprClass:
  case Expr::LambdaExprClass:
    return Cl::CL_ClassTemporary;

  case Expr::VAArgExprClass:
    return ClassifyUnnamed(Ctx, E->getType());

  case Expr::DesignatedInitExprClass:
    return ClassifyInternal(Ctx, cast<DesignatedInitExpr>(E)->getInit());

  case Expr::StmtExprClass: {
    const CompoundStmt *S = cast<StmtExpr>(E)->getSubStmt();
    if (const Expr *LastExpr = dyn_cast_or_null<Expr>(S->body_back()))
      return ClassifyUnnamed(Ctx, LastExpr->getType());
    return Cl::CL_PRValue;
  }

  case Expr::CXXUuidofExprClass:
    return Cl::CL_LValue;

  case Expr::PackExpansionExprClass:
    return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());

  case Expr::MaterializeTemporaryExprClass:
    return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
              ? Cl::CL_LValue 
              : Cl::CL_XValue;

  case Expr::InitListExprClass:
    // An init list can be an lvalue if it is bound to a reference and
    // contains only one element. In that case, we look at that element
    // for an exact classification. Init list creation takes care of the
    // value kind for us, so we only need to fine-tune.
    if (E->isRValue())
      return ClassifyExprValueKind(Lang, E, E->getValueKind());
    assert(cast<InitListExpr>(E)->getNumInits() == 1 &&
           "Only 1-element init lists can be glvalues.");
    return ClassifyInternal(Ctx, cast<InitListExpr>(E)->getInit(0));
  }

  llvm_unreachable("unhandled expression kind in classification");
}

/// ClassifyDecl - Return the classification of an expression referencing the
/// given declaration.
static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) {
  // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a
  //   function, variable, or data member and a prvalue otherwise.
  // In C, functions are not lvalues.
  // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an
  // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to
  // special-case this.

  if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
    return Cl::CL_MemberFunction;

  bool islvalue;
  if (const NonTypeTemplateParmDecl *NTTParm =
        dyn_cast<NonTypeTemplateParmDecl>(D))
    islvalue = NTTParm->getType()->isReferenceType();
  else
    islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
	  isa<IndirectFieldDecl>(D) ||
      (Ctx.getLangOpts().CPlusPlus &&
        (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)));

  return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
}

/// ClassifyUnnamed - Return the classification of an expression yielding an
/// unnamed value of the given type. This applies in particular to function
/// calls and casts.
static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) {
  // In C, function calls are always rvalues.
  if (!Ctx.getLangOpts().CPlusPlus) return Cl::CL_PRValue;

  // C++ [expr.call]p10: A function call is an lvalue if the result type is an
  //   lvalue reference type or an rvalue reference to function type, an xvalue
  //   if the result type is an rvalue reference to object type, and a prvalue
  //   otherwise.
  if (T->isLValueReferenceType())
    return Cl::CL_LValue;
  const RValueReferenceType *RV = T->getAs<RValueReferenceType>();
  if (!RV) // Could still be a class temporary, though.
    return ClassifyTemporary(T);

  return RV->getPointeeType()->isFunctionType() ? Cl::CL_LValue : Cl::CL_XValue;
}

static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) {
  if (E->getType() == Ctx.UnknownAnyTy)
    return (isa<FunctionDecl>(E->getMemberDecl())
              ? Cl::CL_PRValue : Cl::CL_LValue);

  // Handle C first, it's easier.
  if (!Ctx.getLangOpts().CPlusPlus) {
    // C99 6.5.2.3p3
    // For dot access, the expression is an lvalue if the first part is. For
    // arrow access, it always is an lvalue.
    if (E->isArrow())
      return Cl::CL_LValue;
    // ObjC property accesses are not lvalues, but get special treatment.
    Expr *Base = E->getBase()->IgnoreParens();
    if (isa<ObjCPropertyRefExpr>(Base))
      return Cl::CL_SubObjCPropertySetting;
    return ClassifyInternal(Ctx, Base);
  }

  NamedDecl *Member = E->getMemberDecl();
  // C++ [expr.ref]p3: E1->E2 is converted to the equivalent form (*(E1)).E2.
  // C++ [expr.ref]p4: If E2 is declared to have type "reference to T", then
  //   E1.E2 is an lvalue.
  if (ValueDecl *Value = dyn_cast<ValueDecl>(Member))
    if (Value->getType()->isReferenceType())
      return Cl::CL_LValue;

  //   Otherwise, one of the following rules applies.
  //   -- If E2 is a static member [...] then E1.E2 is an lvalue.
  if (isa<VarDecl>(Member) && Member->getDeclContext()->isRecord())
    return Cl::CL_LValue;

  //   -- If E2 is a non-static data member [...]. If E1 is an lvalue, then
  //      E1.E2 is an lvalue; if E1 is an xvalue, then E1.E2 is an xvalue;
  //      otherwise, it is a prvalue.
  if (isa<FieldDecl>(Member)) {
    // *E1 is an lvalue
    if (E->isArrow())
      return Cl::CL_LValue;
    Expr *Base = E->getBase()->IgnoreParenImpCasts();
    if (isa<ObjCPropertyRefExpr>(Base))
      return Cl::CL_SubObjCPropertySetting;
    return ClassifyInternal(Ctx, E->getBase());
  }

  //   -- If E2 is a [...] member function, [...]
  //      -- If it refers to a static member function [...], then E1.E2 is an
  //         lvalue; [...]
  //      -- Otherwise [...] E1.E2 is a prvalue.
  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member))
    return Method->isStatic() ? Cl::CL_LValue : Cl::CL_MemberFunction;

  //   -- If E2 is a member enumerator [...], the expression E1.E2 is a prvalue.
  // So is everything else we haven't handled yet.
  return Cl::CL_PRValue;
}

static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) {
  assert(Ctx.getLangOpts().CPlusPlus &&
         "This is only relevant for C++.");
  // C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand.
  // Except we override this for writes to ObjC properties.
  if (E->isAssignmentOp())
    return (E->getLHS()->getObjectKind() == OK_ObjCProperty
              ? Cl::CL_PRValue : Cl::CL_LValue);

  // C++ [expr.comma]p1: the result is of the same value category as its right
  //   operand, [...].
  if (E->getOpcode() == BO_Comma)
    return ClassifyInternal(Ctx, E->getRHS());

  // C++ [expr.mptr.oper]p6: The result of a .* expression whose second operand
  //   is a pointer to a data member is of the same value category as its first
  //   operand.
  if (E->getOpcode() == BO_PtrMemD)
    return (E->getType()->isFunctionType() ||
            E->hasPlaceholderType(BuiltinType::BoundMember))
             ? Cl::CL_MemberFunction 
             : ClassifyInternal(Ctx, E->getLHS());

  // C++ [expr.mptr.oper]p6: The result of an ->* expression is an lvalue if its
  //   second operand is a pointer to data member and a prvalue otherwise.
  if (E->getOpcode() == BO_PtrMemI)
    return (E->getType()->isFunctionType() ||
            E->hasPlaceholderType(BuiltinType::BoundMember))
             ? Cl::CL_MemberFunction 
             : Cl::CL_LValue;

  // All other binary operations are prvalues.
  return Cl::CL_PRValue;
}

static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
                                     const Expr *False) {
  assert(Ctx.getLangOpts().CPlusPlus &&
         "This is only relevant for C++.");

  // C++ [expr.cond]p2
  //   If either the second or the third operand has type (cv) void, [...]
  //   the result [...] is a prvalue.
  if (True->getType()->isVoidType() || False->getType()->isVoidType())
    return Cl::CL_PRValue;

  // Note that at this point, we have already performed all conversions
  // according to [expr.cond]p3.
  // C++ [expr.cond]p4: If the second and third operands are glvalues of the
  //   same value category [...], the result is of that [...] value category.
  // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
  Cl::Kinds LCl = ClassifyInternal(Ctx, True),
            RCl = ClassifyInternal(Ctx, False);
  return LCl == RCl ? LCl : Cl::CL_PRValue;
}

static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
                                       Cl::Kinds Kind, SourceLocation &Loc) {
  // As a general rule, we only care about lvalues. But there are some rvalues
  // for which we want to generate special results.
  if (Kind == Cl::CL_PRValue) {
    // For the sake of better diagnostics, we want to specifically recognize
    // use of the GCC cast-as-lvalue extension.
    if (const ExplicitCastExpr *CE =
          dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) {
      if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) {
        Loc = CE->getExprLoc();
        return Cl::CM_LValueCast;
      }
    }
  }
  if (Kind != Cl::CL_LValue)
    return Cl::CM_RValue;

  // This is the lvalue case.
  // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6)
  if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType())
    return Cl::CM_Function;

  // Assignment to a property in ObjC is an implicit setter access. But a
  // setter might not exist.
  if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
    if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0)
      return Cl::CM_NoSetterProperty;
  }

  CanQualType CT = Ctx.getCanonicalType(E->getType());
  // Const stuff is obviously not modifiable.
  if (CT.isConstQualified())
    return Cl::CM_ConstQualified;

  // Arrays are not modifiable, only their elements are.
  if (CT->isArrayType())
    return Cl::CM_ArrayType;
  // Incomplete types are not modifiable.
  if (CT->isIncompleteType())
    return Cl::CM_IncompleteType;

  // Records with any const fields (recursively) are not modifiable.
  if (const RecordType *R = CT->getAs<RecordType>()) {
    assert((E->getObjectKind() == OK_ObjCProperty ||
            !Ctx.getLangOpts().CPlusPlus) &&
           "C++ struct assignment should be resolved by the "
           "copy assignment operator.");
    if (R->hasConstFields())
      return Cl::CM_ConstQualified;
  }

  return Cl::CM_Modifiable;
}

Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
  Classification VC = Classify(Ctx);
  switch (VC.getKind()) {
  case Cl::CL_LValue: return LV_Valid;
  case Cl::CL_XValue: return LV_InvalidExpression;
  case Cl::CL_Function: return LV_NotObjectType;
  case Cl::CL_Void: return LV_InvalidExpression;
  case Cl::CL_AddressableVoid: return LV_IncompleteVoidType;
  case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents;
  case Cl::CL_MemberFunction: return LV_MemberFunction;
  case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
  case Cl::CL_ClassTemporary: return LV_ClassTemporary;
  case Cl::CL_ArrayTemporary: return LV_ArrayTemporary;
  case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression;
  case Cl::CL_PRValue: return LV_InvalidExpression;
  }
  llvm_unreachable("Unhandled kind");
}

Expr::isModifiableLvalueResult
Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
  SourceLocation dummy;
  Classification VC = ClassifyModifiable(Ctx, Loc ? *Loc : dummy);
  switch (VC.getKind()) {
  case Cl::CL_LValue: break;
  case Cl::CL_XValue: return MLV_InvalidExpression;
  case Cl::CL_Function: return MLV_NotObjectType;
  case Cl::CL_Void: return MLV_InvalidExpression;
  case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType;
  case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents;
  case Cl::CL_MemberFunction: return MLV_MemberFunction;
  case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
  case Cl::CL_ClassTemporary: return MLV_ClassTemporary;
  case Cl::CL_ArrayTemporary: return MLV_ArrayTemporary;
  case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression;
  case Cl::CL_PRValue:
    return VC.getModifiable() == Cl::CM_LValueCast ?
      MLV_LValueCast : MLV_InvalidExpression;
  }
  assert(VC.getKind() == Cl::CL_LValue && "Unhandled kind");
  switch (VC.getModifiable()) {
  case Cl::CM_Untested: llvm_unreachable("Did not test modifiability");
  case Cl::CM_Modifiable: return MLV_Valid;
  case Cl::CM_RValue: llvm_unreachable("CM_RValue and CL_LValue don't match");
  case Cl::CM_Function: return MLV_NotObjectType;
  case Cl::CM_LValueCast:
    llvm_unreachable("CM_LValueCast and CL_LValue don't match");
  case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
  case Cl::CM_ConstQualified: return MLV_ConstQualified;
  case Cl::CM_ArrayType: return MLV_ArrayType;
  case Cl::CM_IncompleteType: return MLV_IncompleteType;
  }
  llvm_unreachable("Unhandled modifiable type");
}
