Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Sema/SemaExpr.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 5,540 Lines • ▼ Show 20 Lines | if (!LangOpts.isSubscriptPointerArithmetic()) { | ||||
Diag(LLoc, diag::err_subscript_nonfragile_interface) | Diag(LLoc, diag::err_subscript_nonfragile_interface) | ||||
<< ResultType << BaseExpr->getSourceRange(); | << ResultType << BaseExpr->getSourceRange(); | ||||
return ExprError(); | return ExprError(); | ||||
} | } | ||||
} else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) { | } else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) { | ||||
BaseExpr = LHSExp; // vectors: V[123] | BaseExpr = LHSExp; // vectors: V[123] | ||||
IndexExpr = RHSExp; | IndexExpr = RHSExp; | ||||
// We apply C++ DR1213 to vector subscripting too. | // We apply C++ DR1213 to vector subscripting too. | ||||
if (getLangOpts().CPlusPlus11 && LHSExp->getValueKind() == VK_PRValue) { | if (getLangOpts().CPlusPlus11 && LHSExp->isPRValue()) { | ||||
ExprResult Materialized = TemporaryMaterializationConversion(LHSExp); | ExprResult Materialized = TemporaryMaterializationConversion(LHSExp); | ||||
if (Materialized.isInvalid()) | if (Materialized.isInvalid()) | ||||
return ExprError(); | return ExprError(); | ||||
LHSExp = Materialized.get(); | LHSExp = Materialized.get(); | ||||
} | } | ||||
VK = LHSExp->getValueKind(); | VK = LHSExp->getValueKind(); | ||||
aaronpuchert: There might be a certain benefit to using `LHSExp->getValueKind()` above when we use it here… | |||||
Or just making the same kind of change here again: if (!LHSExp->isRValue()) OK = OK_VectorComponent; VK = LHSExp->getValueKind(); mizvekov: Or just making the same kind of change here again:
```
if (!LHSExp->isRValue())
OK =… | |||||
if (VK != VK_PRValue) | if (VK != VK_PRValue) | ||||
OK = OK_VectorComponent; | OK = OK_VectorComponent; | ||||
ResultType = VTy->getElementType(); | ResultType = VTy->getElementType(); | ||||
QualType BaseType = BaseExpr->getType(); | QualType BaseType = BaseExpr->getType(); | ||||
Qualifiers BaseQuals = BaseType.getQualifiers(); | Qualifiers BaseQuals = BaseType.getQualifiers(); | ||||
Qualifiers MemberQuals = ResultType.getQualifiers(); | Qualifiers MemberQuals = ResultType.getQualifiers(); | ||||
Qualifiers Combined = BaseQuals + MemberQuals; | Qualifiers Combined = BaseQuals + MemberQuals; | ||||
▲ Show 20 Lines • Show All 4,590 Lines • ▼ Show 20 Lines | QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, | ||||
} | } | ||||
if (!LHSVecType) { | if (!LHSVecType) { | ||||
if (isa<ExtVectorType>(RHSVecType)) { | if (isa<ExtVectorType>(RHSVecType)) { | ||||
if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS), | if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS), | ||||
LHSType, RHSVecType->getElementType(), | LHSType, RHSVecType->getElementType(), | ||||
RHSType, DiagID)) | RHSType, DiagID)) | ||||
return RHSType; | return RHSType; | ||||
} else { | } else { | ||||
if (LHS.get()->getValueKind() == VK_LValue || | if (LHS.get()->isLValue() || | ||||
!tryGCCVectorConvertAndSplat(*this, &LHS, &RHS)) | !tryGCCVectorConvertAndSplat(*this, &LHS, &RHS)) | ||||
return RHSType; | return RHSType; | ||||
} | } | ||||
} | } | ||||
// FIXME: The code below also handles conversion between vectors and | // FIXME: The code below also handles conversion between vectors and | ||||
// non-scalars, we should break this down into fine grained specific checks | // non-scalars, we should break this down into fine grained specific checks | ||||
// and emit proper diagnostics. | // and emit proper diagnostics. | ||||
▲ Show 20 Lines • Show All 4,763 Lines • ▼ Show 20 Lines | case UO_LNot: // logical negation | ||||
break; | break; | ||||
case UO_Real: | case UO_Real: | ||||
case UO_Imag: | case UO_Imag: | ||||
resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real); | resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real); | ||||
// _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary | // _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary | ||||
// complex l-values to ordinary l-values and all other values to r-values. | // complex l-values to ordinary l-values and all other values to r-values. | ||||
if (Input.isInvalid()) return ExprError(); | if (Input.isInvalid()) return ExprError(); | ||||
if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) { | if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) { | ||||
if (Input.get()->getValueKind() != VK_PRValue && | if (Input.get()->isGLValue() && | ||||
Input.get()->getObjectKind() == OK_Ordinary) | Input.get()->getObjectKind() == OK_Ordinary) | ||||
VK = Input.get()->getValueKind(); | VK = Input.get()->getValueKind(); | ||||
} else if (!getLangOpts().CPlusPlus) { | } else if (!getLangOpts().CPlusPlus) { | ||||
// In C, a volatile scalar is read by __imag. In C++, it is not. | // In C, a volatile scalar is read by __imag. In C++, it is not. | ||||
Input = DefaultLvalueConversion(Input.get()); | Input = DefaultLvalueConversion(Input.get()); | ||||
} | } | ||||
break; | break; | ||||
case UO_Extension: | case UO_Extension: | ||||
▲ Show 20 Lines • Show All 4,220 Lines • ▼ Show 20 Lines | struct RebuildUnknownAnyFunction | ||||
ExprResult VisitUnaryAddrOf(UnaryOperator *E) { | ExprResult VisitUnaryAddrOf(UnaryOperator *E) { | ||||
ExprResult SubResult = Visit(E->getSubExpr()); | ExprResult SubResult = Visit(E->getSubExpr()); | ||||
if (SubResult.isInvalid()) return ExprError(); | if (SubResult.isInvalid()) return ExprError(); | ||||
Expr *SubExpr = SubResult.get(); | Expr *SubExpr = SubResult.get(); | ||||
E->setSubExpr(SubExpr); | E->setSubExpr(SubExpr); | ||||
E->setType(S.Context.getPointerType(SubExpr->getType())); | E->setType(S.Context.getPointerType(SubExpr->getType())); | ||||
assert(E->getValueKind() == VK_PRValue); | assert(E->isPRValue()); | ||||
assert(E->getObjectKind() == OK_Ordinary); | assert(E->getObjectKind() == OK_Ordinary); | ||||
return E; | return E; | ||||
} | } | ||||
ExprResult resolveDecl(Expr *E, ValueDecl *VD) { | ExprResult resolveDecl(Expr *E, ValueDecl *VD) { | ||||
if (!isa<FunctionDecl>(VD)) return VisitExpr(E); | if (!isa<FunctionDecl>(VD)) return VisitExpr(E); | ||||
E->setType(VD->getType()); | E->setType(VD->getType()); | ||||
assert(E->getValueKind() == VK_PRValue); | assert(E->isPRValue()); | ||||
if (S.getLangOpts().CPlusPlus && | if (S.getLangOpts().CPlusPlus && | ||||
!(isa<CXXMethodDecl>(VD) && | !(isa<CXXMethodDecl>(VD) && | ||||
cast<CXXMethodDecl>(VD)->isInstance())) | cast<CXXMethodDecl>(VD)->isInstance())) | ||||
E->setValueKind(VK_LValue); | E->setValueKind(VK_LValue); | ||||
return E; | return E; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | ExprResult VisitUnaryAddrOf(UnaryOperator *E) { | ||||
} | } | ||||
if (isa<CallExpr>(E->getSubExpr())) { | if (isa<CallExpr>(E->getSubExpr())) { | ||||
S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call) | S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call) | ||||
<< E->getSourceRange(); | << E->getSourceRange(); | ||||
return ExprError(); | return ExprError(); | ||||
} | } | ||||
assert(E->getValueKind() == VK_PRValue); | assert(E->isPRValue()); | ||||
assert(E->getObjectKind() == OK_Ordinary); | assert(E->getObjectKind() == OK_Ordinary); | ||||
E->setType(DestType); | E->setType(DestType); | ||||
// Build the sub-expression as if it were an object of the pointee type. | // Build the sub-expression as if it were an object of the pointee type. | ||||
DestType = Ptr->getPointeeType(); | DestType = Ptr->getPointeeType(); | ||||
ExprResult SubResult = Visit(E->getSubExpr()); | ExprResult SubResult = Visit(E->getSubExpr()); | ||||
if (SubResult.isInvalid()) return ExprError(); | if (SubResult.isInvalid()) return ExprError(); | ||||
E->setSubExpr(SubResult.get()); | E->setSubExpr(SubResult.get()); | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) { | ||||
E->setValueKind(Expr::getValueKindForType(DestType)); | E->setValueKind(Expr::getValueKindForType(DestType)); | ||||
return S.MaybeBindToTemporary(E); | return S.MaybeBindToTemporary(E); | ||||
} | } | ||||
ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) { | ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) { | ||||
// The only case we should ever see here is a function-to-pointer decay. | // The only case we should ever see here is a function-to-pointer decay. | ||||
if (E->getCastKind() == CK_FunctionToPointerDecay) { | if (E->getCastKind() == CK_FunctionToPointerDecay) { | ||||
assert(E->getValueKind() == VK_PRValue); | assert(E->isPRValue()); | ||||
assert(E->getObjectKind() == OK_Ordinary); | assert(E->getObjectKind() == OK_Ordinary); | ||||
E->setType(DestType); | E->setType(DestType); | ||||
// Rebuild the sub-expression as the pointee (function) type. | // Rebuild the sub-expression as the pointee (function) type. | ||||
DestType = DestType->castAs<PointerType>()->getPointeeType(); | DestType = DestType->castAs<PointerType>()->getPointeeType(); | ||||
ExprResult Result = Visit(E->getSubExpr()); | ExprResult Result = Visit(E->getSubExpr()); | ||||
if (!Result.isUsable()) return ExprError(); | if (!Result.isUsable()) return ExprError(); | ||||
E->setSubExpr(Result.get()); | E->setSubExpr(Result.get()); | ||||
return E; | return E; | ||||
} else if (E->getCastKind() == CK_LValueToRValue) { | } else if (E->getCastKind() == CK_LValueToRValue) { | ||||
assert(E->getValueKind() == VK_PRValue); | assert(E->isPRValue()); | ||||
assert(E->getObjectKind() == OK_Ordinary); | assert(E->getObjectKind() == OK_Ordinary); | ||||
assert(isa<BlockPointerType>(E->getType())); | assert(isa<BlockPointerType>(E->getType())); | ||||
E->setType(DestType); | E->setType(DestType); | ||||
// The sub-expression has to be a lvalue reference, so rebuild it as such. | // The sub-expression has to be a lvalue reference, so rebuild it as such. | ||||
DestType = S.Context.getLValueReferenceType(DestType); | DestType = S.Context.getLValueReferenceType(DestType); | ||||
▲ Show 20 Lines • Show All 400 Lines • Show Last 20 Lines |
There might be a certain benefit to using LHSExp->getValueKind() above when we use it here again: that makes it more obvious what we're trying to achieve in that if. (Namely changing the value category.)