Switch a lot of call-sites over to using the new value-kind calculations.

llvm-svn: 120084
This commit is contained in:
John McCall 2010-11-24 05:12:34 +00:00
parent e2ea8bf945
commit 086a464e24
13 changed files with 61 additions and 54 deletions

View File

@ -127,19 +127,25 @@ public:
bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
SourceRange &R2, ASTContext &Ctx) const;
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
/// - name, where name must be a variable
/// - e[i]
/// - (e), where e must be an lvalue
/// - e.name, where e must be an lvalue
/// - e->name
/// - *e, the type of e cannot be a function type
/// - string-constant
/// - reference type [C++ [expr]]
/// - b ? x : y, where x and y are lvalues of suitable types [C++]
/// isLValue - True if this expression is an "l-value" according to
/// the rules of the current language. C and C++ give somewhat
/// different rules for this concept, but in general, the result of
/// an l-value expression identifies a specific object whereas the
/// result of an r-value expression is a value detached from any
/// specific storage.
///
enum isLvalueResult {
/// C++0x divides the concept of "r-value" into pure r-values
/// ("pr-values") and so-called expiring values ("x-values"), which
/// identify specific objects that can be safely cannibalized for
/// their resources. This is an unfortunate abuse of terminology on
/// the part of the C++ committee. In Clang, when we say "r-value",
/// we generally mean a pr-value.
bool isLValue() const { return getValueKind() == VK_LValue; }
bool isRValue() const { return getValueKind() == VK_RValue; }
bool isXValue() const { return getValueKind() == VK_XValue; }
bool isGLValue() const { return getValueKind() != VK_RValue; }
enum LValueClassification {
LV_Valid,
LV_NotObjectType,
LV_IncompleteVoidType,
@ -149,7 +155,8 @@ public:
LV_SubObjCPropertySetting,
LV_ClassTemporary
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
/// Reasons why an expression might not be an l-value.
LValueClassification ClassifyLValue(ASTContext &Ctx) const;
/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
/// does not have an incomplete type, does not have a const-qualified type,

View File

@ -2378,7 +2378,7 @@ static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
// Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
// defined as T&, otherwise decltype(e) is defined as T.
if (e->isLvalue(Context) == Expr::LV_Valid)
if (e->isLValue())
T = Context.getLValueReferenceType(T);
return T;

View File

@ -1460,7 +1460,7 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
bool Expr::isBoundMemberFunction(ASTContext &Ctx) const {
if (isTypeDependent())
return false;
return isLvalue(Ctx) == Expr::LV_MemberFunction;
return ClassifyLValue(Ctx) == Expr::LV_MemberFunction;
}
static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1,

View File

@ -529,7 +529,7 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
return Cl::CM_Modifiable;
}
Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const {
Classification VC = Classify(Ctx);
switch (VC.getKind()) {
case Cl::CL_LValue: return LV_Valid;

View File

@ -192,7 +192,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
}
RValue RV;
if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) {
if (E->isLValue()) {
// Emit the expression as an lvalue.
LValue LV = CGF.EmitLValue(E);
if (LV.isPropertyRef() || LV.isKVCRef()) {
@ -235,8 +235,8 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
continue;
}
} else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
if (ME->getBase()->isLvalue(CGF.getContext()) != Expr::LV_Valid &&
ME->getBase()->getType()->isRecordType()) {
if (!ME->isArrow() && ME->getBase()->isRValue()) {
assert(ME->getBase()->getType()->isRecordType());
if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
E = ME->getBase();
Adjustments.push_back(SubobjectAdjustment(Field));
@ -1515,7 +1515,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
Base = MakeAddrLValue(Ptr, PT->getPointeeType());
Base.getQuals().removeObjCGCAttr();
} else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) {
} else if (E->getBase()->isGLValue()) {
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
// emit the base as an lvalue.
assert(E->getBase()->getType()->isVectorType());
@ -1711,7 +1711,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
LValue
CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator *E) {
if (E->isLvalue(getContext()) == Expr::LV_Valid) {
if (E->isGLValue()) {
if (int Cond = ConstantFoldsToSimpleInteger(E->getCond())) {
Expr *Live = Cond == 1 ? E->getLHS() : E->getRHS();
if (Live)

View File

@ -1474,7 +1474,7 @@ Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
// If it's an l-value, load through the appropriate subobject l-value.
// Note that we have to ask E because Op might be an l-value that
// this won't work for, e.g. an Obj-C property.
if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid)
if (E->isGLValue())
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
.getScalarVal();
@ -1491,7 +1491,7 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
// If it's an l-value, load through the appropriate subobject l-value.
// Note that we have to ask E because Op might be an l-value that
// this won't work for, e.g. an Obj-C property.
if (Op->isLvalue(CGF.getContext()) == Expr::LV_Valid)
if (Op->isGLValue())
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType())
.getScalarVal();
@ -2548,7 +2548,7 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
const llvm::Type *ClassPtrTy = ConvertType(E->getType());
Expr *BaseExpr = E->getBase();
if (BaseExpr->isLvalue(getContext()) != Expr::LV_Valid) {
if (BaseExpr->isRValue()) {
V = CreateTempAlloca(ClassPtrTy, "resval");
llvm::Value *Src = EmitScalarExpr(BaseExpr);
Builder.CreateStore(Src, V);

View File

@ -375,7 +375,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
return;
}
} else if (DestReference->isLValueReferenceType()) {
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
if (!SrcExpr->isLValue()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
<< CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
}
@ -698,7 +698,7 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
if (!R)
return TC_NotApplicable;
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid)
if (!SrcExpr->isLValue())
return TC_NotApplicable;
// Because we try the reference downcast before this function, from now on
@ -739,7 +739,7 @@ TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
return TC_NotApplicable;
}
bool RValueRef = DestReference->isRValueReferenceType();
if (!RValueRef && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
if (!RValueRef && !SrcExpr->isLValue()) {
// We know the left side is an lvalue reference, so we can suggest a reason.
msg = diag::err_bad_cxx_cast_rvalue;
return TC_NotApplicable;
@ -1049,7 +1049,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
QualType SrcType = SrcExpr->getType();
if (const LValueReferenceType *DestTypeTmp =
DestType->getAs<LValueReferenceType>()) {
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
if (!SrcExpr->isLValue()) {
// Cannot const_cast non-lvalue to lvalue reference type. But if this
// is C-style, static_cast might find a way, so we simply suggest a
// message and tell the parent to keep searching.
@ -1152,7 +1152,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
bool LValue = DestTypeTmp->isLValueReferenceType();
if (LValue && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
if (LValue && !SrcExpr->isLValue()) {
// Cannot cast non-lvalue to reference type. See the similar comment in
// const_cast.
msg = diag::err_bad_cxx_cast_rvalue;

View File

@ -238,8 +238,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
// An lvalue or rvalue of type "array of N T" or "array of unknown bound of
// T" can be converted to an rvalue of type "pointer to T".
//
if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
E->isLvalue(Context) == Expr::LV_Valid)
if (getLangOptions().C99 || getLangOptions().CPlusPlus || E->isLValue())
ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
CK_ArrayToPointerDecay);
}
@ -252,7 +251,7 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
assert(!Ty.isNull() && "DefaultFunctionArrayLvalueConversion - missing type");
if (!Ty->isDependentType() && Ty.hasQualifiers() &&
(!getLangOptions().CPlusPlus || !Ty->isRecordType()) &&
E->isLvalue(Context) == Expr::LV_Valid) {
E->isLValue()) {
// C++ [conv.lval]p1:
// [...] If T is a non-class type, the type of the rvalue is the
// cv-unqualified version of T. Otherwise, the type of the
@ -789,10 +788,16 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
MarkDeclarationReferenced(NameInfo.getLoc(), D);
return Owned(DeclRefExpr::Create(Context,
Expr *E = DeclRefExpr::Create(Context,
SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
SS? SS->getRange() : SourceRange(),
D, NameInfo, Ty, VK));
SS? SS->getRange() : SourceRange(),
D, NameInfo, Ty, VK);
// Just in case we're building an illegal pointer-to-member.
if (isa<FieldDecl>(D) && cast<FieldDecl>(D)->getBitWidth())
E->setObjectKind(OK_BitField);
return Owned(E);
}
static ExprResult
@ -7045,7 +7050,7 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp,
// expressions here, but the result of one is always an lvalue anyway.
}
NamedDecl *dcl = getPrimaryDecl(op);
Expr::isLvalueResult lval = op->isLvalue(S.Context);
Expr::LValueClassification lval = op->ClassifyLValue(S.Context);
if (lval == Expr::LV_ClassTemporary) {
bool sfinae = S.isSFINAEContext();
@ -7091,25 +7096,21 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp,
<< op->getSourceRange();
return QualType();
}
} else if (op->getBitField()) { // C99 6.5.3.2p1
} else if (op->getObjectKind() == OK_BitField) { // C99 6.5.3.2p1
// The operand cannot be a bit-field
S.Diag(OpLoc, diag::err_typecheck_address_of)
<< "bit-field" << op->getSourceRange();
return QualType();
} else if (op->refersToVectorElement()) {
} else if (op->getObjectKind() == OK_VectorComponent) {
// The operand cannot be an element of a vector
S.Diag(OpLoc, diag::err_typecheck_address_of)
<< "vector element" << op->getSourceRange();
return QualType();
} else if (isa<ObjCPropertyRefExpr>(op)) {
} else if (op->getObjectKind() == OK_ObjCProperty) {
// cannot take address of a property expression.
S.Diag(OpLoc, diag::err_typecheck_address_of)
<< "property expression" << op->getSourceRange();
return QualType();
} else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(op)) {
// FIXME: Can LHS ever be null here?
if (!CheckAddressOfOperand(S, CO->getTrueExpr(), OpLoc).isNull())
return CheckAddressOfOperand(S, CO->getFalseExpr(), OpLoc);
} else if (dcl) { // C99 6.5.3.2p1
// We have an lvalue with a decl. Make sure the decl is not declared
// with the register storage-class specifier.

View File

@ -2460,7 +2460,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
// can be converted to match an operand expression E2 of type T2 is defined
// as follows:
// -- If E2 is an lvalue:
bool ToIsLvalue = (To->isLvalue(Self.Context) == Expr::LV_Valid);
bool ToIsLvalue = To->isLValue();
if (ToIsLvalue) {
// E1 can be converted to match E2 if E1 can be implicitly converted to
// type "lvalue reference to T2", subject to the constraint that in the

View File

@ -4173,7 +4173,7 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_ReferenceInitFailed:
S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
<< DestType.getNonReferenceType()
<< (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
<< Args[0]->isLValue()
<< Args[0]->getType()
<< Args[0]->getSourceRange();
break;
@ -4182,7 +4182,7 @@ bool InitializationSequence::Diagnose(Sema &S,
S.Diag(Kind.getLocation(), diag::err_init_conversion_failed)
<< (int)Entity.getKind()
<< DestType
<< (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
<< Args[0]->isLValue()
<< Args[0]->getType()
<< Args[0]->getSourceRange();
break;

View File

@ -1003,8 +1003,8 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
// Lvalue-to-rvalue conversion (C++ 4.1):
// An lvalue (3.10) of a non-function, non-array type T can be
// converted to an rvalue.
Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
if (argIsLvalue == Expr::LV_Valid &&
bool argIsLValue = From->isLValue();
if (argIsLValue &&
!FromType->isFunctionType() && !FromType->isArrayType() &&
S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
SCS.First = ICK_Lvalue_To_Rvalue;
@ -1036,7 +1036,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
SCS.setAllToTypes(FromType);
return true;
}
} else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
} else if (FromType->isFunctionType() && argIsLValue) {
// Function-to-pointer conversion (C++ 4.3).
SCS.First = ICK_Function_To_Pointer;

View File

@ -977,8 +977,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
diag::err_non_variable_decl_in_for));
} else {
Expr *FirstE = cast<Expr>(First);
if (!FirstE->isTypeDependent() &&
FirstE->isLvalue(Context) != Expr::LV_Valid)
if (!FirstE->isTypeDependent() && !FirstE->isLValue())
return StmtError(Diag(First->getLocStart(),
diag::err_selector_element_not_lvalue)
<< First->getSourceRange());
@ -1312,13 +1311,13 @@ static bool CheckAsmLValue(const Expr *E, Sema &S) {
if (E->isTypeDependent())
return false;
if (E->isLvalue(S.Context) == Expr::LV_Valid)
if (E->isLValue())
return false; // Cool, this is an lvalue.
// Okay, this is not an lvalue, but perhaps it is the result of a cast that we
// are supposed to allow.
const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
if (E != E2 && E2->isLvalue(S.Context) == Expr::LV_Valid) {
if (E != E2 && E2->isLValue()) {
if (!S.getLangOptions().HeinousExtensions)
S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
<< E->getSourceRange();

View File

@ -1757,7 +1757,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// type deduction.
if (ParamRefType->isRValueReferenceType() &&
ParamRefType->getAs<TemplateTypeParmType>() &&
Args[I]->isLvalue(Context) == Expr::LV_Valid)
Args[I]->isLValue())
ArgType = Context.getLValueReferenceType(ArgType);
} else {
// C++ [temp.deduct.call]p2: