Changeset View
Changeset View
Standalone View
Standalone View
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,512 Lines • ▼ Show 20 Lines | Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, | ||||
Ty = CreateParsedType(castType, castTInfo); | Ty = CreateParsedType(castType, castTInfo); | ||||
bool isVectorLiteral = false; | bool isVectorLiteral = false; | ||||
// Check for an altivec or OpenCL literal, | // Check for an altivec or OpenCL literal, | ||||
// i.e. all the elements are integer constants. | // i.e. all the elements are integer constants. | ||||
ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr); | ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr); | ||||
ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr); | ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr); | ||||
if ((getLangOpts().AltiVec || getLangOpts().OpenCL) | if ((getLangOpts().AltiVec || getLangOpts().ZVector || getLangOpts().OpenCL) | ||||
&& castType->isVectorType() && (PE || PLE)) { | && castType->isVectorType() && (PE || PLE)) { | ||||
if (PLE && PLE->getNumExprs() == 0) { | if (PLE && PLE->getNumExprs() == 0) { | ||||
Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer); | Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer); | ||||
return ExprError(); | return ExprError(); | ||||
} | } | ||||
if (PE || PLE->getNumExprs() == 1) { | if (PE || PLE->getNumExprs() == 1) { | ||||
Expr *E = (PE ? PE->getSubExpr() : PLE->getExpr(0)); | Expr *E = (PE ? PE->getSubExpr() : PLE->getExpr(0)); | ||||
if (!E->getType()->isVectorType()) | if (!E->getType()->isVectorType()) | ||||
▲ Show 20 Lines • Show All 540 Lines • ▼ Show 20 Lines | OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond, | ||||
if (checkOpenCLConditionVector(S, Cond.get(), QuestionLoc)) | if (checkOpenCLConditionVector(S, Cond.get(), QuestionLoc)) | ||||
return QualType(); | return QualType(); | ||||
// If either operand is a vector then find the vector type of the | // If either operand is a vector then find the vector type of the | ||||
// result as specified in OpenCL v1.1 s6.3.i. | // result as specified in OpenCL v1.1 s6.3.i. | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
QualType VecResTy = S.CheckVectorOperands(LHS, RHS, QuestionLoc, | QualType VecResTy = S.CheckVectorOperands(LHS, RHS, QuestionLoc, | ||||
/*isCompAssign*/false); | /*isCompAssign*/false, | ||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/false); | |||||
if (VecResTy.isNull()) return QualType(); | if (VecResTy.isNull()) return QualType(); | ||||
// The result type must match the condition type as specified in | // The result type must match the condition type as specified in | ||||
// OpenCL v1.1 s6.11.6. | // OpenCL v1.1 s6.11.6. | ||||
if (checkVectorResult(S, CondTy, VecResTy, QuestionLoc)) | if (checkVectorResult(S, CondTy, VecResTy, QuestionLoc)) | ||||
return QualType(); | return QualType(); | ||||
return VecResTy; | return VecResTy; | ||||
} | } | ||||
Show All 34 Lines | QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, | ||||
if (Cond.isInvalid()) | if (Cond.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
if (checkCondition(*this, Cond.get(), QuestionLoc)) | if (checkCondition(*this, Cond.get(), QuestionLoc)) | ||||
return QualType(); | return QualType(); | ||||
// Now check the two expressions. | // Now check the two expressions. | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) | RHS.get()->getType()->isVectorType()) | ||||
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); | return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false, | ||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/false); | |||||
QualType ResTy = UsualArithmeticConversions(LHS, RHS); | QualType ResTy = UsualArithmeticConversions(LHS, RHS); | ||||
if (LHS.isInvalid() || RHS.isInvalid()) | if (LHS.isInvalid() || RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
QualType LHSTy = LHS.get()->getType(); | QualType LHSTy = LHS.get()->getType(); | ||||
QualType RHSTy = RHS.get()->getType(); | QualType RHSTy = RHS.get()->getType(); | ||||
▲ Show 20 Lines • Show All 1,124 Lines • ▼ Show 20 Lines | if (scalar) { | ||||
if (scalarCast != CK_Invalid) | if (scalarCast != CK_Invalid) | ||||
*scalar = S.ImpCastExprToType(scalar->get(), vectorEltTy, scalarCast); | *scalar = S.ImpCastExprToType(scalar->get(), vectorEltTy, scalarCast); | ||||
*scalar = S.ImpCastExprToType(scalar->get(), vectorTy, CK_VectorSplat); | *scalar = S.ImpCastExprToType(scalar->get(), vectorTy, CK_VectorSplat); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, | QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, | ||||
SourceLocation Loc, bool IsCompAssign) { | SourceLocation Loc, bool IsCompAssign, | ||||
bool AllowBothBool, | |||||
bool AllowBoolConversions) { | |||||
if (!IsCompAssign) { | if (!IsCompAssign) { | ||||
LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); | LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); | ||||
if (LHS.isInvalid()) | if (LHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
} | } | ||||
RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); | RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); | ||||
if (RHS.isInvalid()) | if (RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
// For conversion purposes, we ignore any qualifiers. | // For conversion purposes, we ignore any qualifiers. | ||||
// For example, "const float" and "float" are equivalent. | // For example, "const float" and "float" are equivalent. | ||||
QualType LHSType = LHS.get()->getType().getUnqualifiedType(); | QualType LHSType = LHS.get()->getType().getUnqualifiedType(); | ||||
QualType RHSType = RHS.get()->getType().getUnqualifiedType(); | QualType RHSType = RHS.get()->getType().getUnqualifiedType(); | ||||
// If the vector types are identical, return. | |||||
if (Context.hasSameType(LHSType, RHSType)) | |||||
return LHSType; | |||||
const VectorType *LHSVecType = LHSType->getAs<VectorType>(); | const VectorType *LHSVecType = LHSType->getAs<VectorType>(); | ||||
const VectorType *RHSVecType = RHSType->getAs<VectorType>(); | const VectorType *RHSVecType = RHSType->getAs<VectorType>(); | ||||
assert(LHSVecType || RHSVecType); | assert(LHSVecType || RHSVecType); | ||||
// AltiVec-style "vector bool op vector bool" combinations are allowed | |||||
// for some operators but not others. | |||||
if (!AllowBothBool && | |||||
LHSVecType && LHSVecType->getVectorKind() == VectorType::AltiVecBool && | |||||
RHSVecType && RHSVecType->getVectorKind() == VectorType::AltiVecBool) | |||||
return InvalidOperands(Loc, LHS, RHS); | |||||
// If the vector types are identical, return. | |||||
if (Context.hasSameType(LHSType, RHSType)) | |||||
return LHSType; | |||||
// If we have compatible AltiVec and GCC vector types, use the AltiVec type. | // If we have compatible AltiVec and GCC vector types, use the AltiVec type. | ||||
if (LHSVecType && RHSVecType && | if (LHSVecType && RHSVecType && | ||||
Context.areCompatibleVectorTypes(LHSType, RHSType)) { | Context.areCompatibleVectorTypes(LHSType, RHSType)) { | ||||
if (isa<ExtVectorType>(LHSVecType)) { | if (isa<ExtVectorType>(LHSVecType)) { | ||||
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast); | RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast); | ||||
return LHSType; | return LHSType; | ||||
} | } | ||||
if (!IsCompAssign) | if (!IsCompAssign) | ||||
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast); | LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast); | ||||
return RHSType; | return RHSType; | ||||
} | } | ||||
// AllowBoolConversions says that bool and non-bool AltiVec vectors | |||||
// can be mixed, with the result being the non-bool type. The non-bool | |||||
// operand must have integer element type. | |||||
if (AllowBoolConversions && LHSVecType && RHSVecType && | |||||
LHSVecType->getNumElements() == RHSVecType->getNumElements() && | |||||
(Context.getTypeSize(LHSVecType->getElementType()) == | |||||
Context.getTypeSize(RHSVecType->getElementType()))) { | |||||
if (LHSVecType->getVectorKind() == VectorType::AltiVecVector && | |||||
LHSVecType->getElementType()->isIntegerType() && | |||||
RHSVecType->getVectorKind() == VectorType::AltiVecBool) { | |||||
RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast); | |||||
return LHSType; | |||||
} | |||||
if (!IsCompAssign && | |||||
LHSVecType->getVectorKind() == VectorType::AltiVecBool && | |||||
RHSVecType->getVectorKind() == VectorType::AltiVecVector && | |||||
RHSVecType->getElementType()->isIntegerType()) { | |||||
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast); | |||||
return RHSType; | |||||
} | |||||
} | |||||
// If there's an ext-vector type and a scalar, try to convert the scalar to | // If there's an ext-vector type and a scalar, try to convert the scalar to | ||||
// the vector element type and splat. | // the vector element type and splat. | ||||
if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) { | if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) { | ||||
if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, | if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, | ||||
LHSVecType->getElementType(), LHSType)) | LHSVecType->getElementType(), LHSType)) | ||||
return LHSType; | return LHSType; | ||||
} | } | ||||
if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) { | if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) { | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, | QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, | ||||
SourceLocation Loc, | SourceLocation Loc, | ||||
bool IsCompAssign, bool IsDiv) { | bool IsCompAssign, bool IsDiv) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) | RHS.get()->getType()->isVectorType()) | ||||
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); | return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, | ||||
/*AllowBothBool*/getLangOpts().AltiVec, | |||||
rsmith: It'd be better to phrase this as a positive language mode check than a negative one (that is… | |||||
Not Done ReplyInline ActionsOK, updated accordingly. uweigand: OK, updated accordingly. | |||||
/*AllowBoolConversions*/false); | |||||
QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign); | QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign); | ||||
if (LHS.isInvalid() || RHS.isInvalid()) | if (LHS.isInvalid() || RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
if (compType.isNull() || !compType->isArithmeticType()) | if (compType.isNull() || !compType->isArithmeticType()) | ||||
return InvalidOperands(Loc, LHS, RHS); | return InvalidOperands(Loc, LHS, RHS); | ||||
Show All 12 Lines | |||||
QualType Sema::CheckRemainderOperands( | QualType Sema::CheckRemainderOperands( | ||||
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
if (LHS.get()->getType()->hasIntegerRepresentation() && | if (LHS.get()->getType()->hasIntegerRepresentation() && | ||||
RHS.get()->getType()->hasIntegerRepresentation()) | RHS.get()->getType()->hasIntegerRepresentation()) | ||||
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); | return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, | ||||
/*AllowBothBool*/getLangOpts().AltiVec, | |||||
/*AllowBoolConversions*/false); | |||||
return InvalidOperands(Loc, LHS, RHS); | return InvalidOperands(Loc, LHS, RHS); | ||||
} | } | ||||
QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign); | QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign); | ||||
if (LHS.isInvalid() || RHS.isInvalid()) | if (LHS.isInvalid() || RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
if (compType.isNull() || !compType->isIntegerType()) | if (compType.isNull() || !compType->isIntegerType()) | ||||
▲ Show 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | |||||
QualType Sema::CheckAdditionOperands( // C99 6.5.6 | QualType Sema::CheckAdditionOperands( // C99 6.5.6 | ||||
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, | ||||
QualType* CompLHSTy) { | QualType* CompLHSTy) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy); | QualType compType = CheckVectorOperands( | ||||
LHS, RHS, Loc, CompLHSTy, | |||||
/*AllowBothBool*/getLangOpts().AltiVec, | |||||
/*AllowBoolConversions*/getLangOpts().ZVector); | |||||
if (CompLHSTy) *CompLHSTy = compType; | if (CompLHSTy) *CompLHSTy = compType; | ||||
return compType; | return compType; | ||||
} | } | ||||
QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy); | QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy); | ||||
if (LHS.isInvalid() || RHS.isInvalid()) | if (LHS.isInvalid() || RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
// C99 6.5.6 | // C99 6.5.6 | ||||
QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, | QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, | ||||
SourceLocation Loc, | SourceLocation Loc, | ||||
QualType* CompLHSTy) { | QualType* CompLHSTy) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy); | QualType compType = CheckVectorOperands( | ||||
LHS, RHS, Loc, CompLHSTy, | |||||
/*AllowBothBool*/getLangOpts().AltiVec, | |||||
/*AllowBoolConversions*/getLangOpts().ZVector); | |||||
if (CompLHSTy) *CompLHSTy = compType; | if (CompLHSTy) *CompLHSTy = compType; | ||||
return compType; | return compType; | ||||
} | } | ||||
QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy); | QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy); | ||||
if (LHS.isInvalid() || RHS.isInvalid()) | if (LHS.isInvalid() || RHS.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
▲ Show 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS, | ||||
bool IsCompAssign) { | bool IsCompAssign) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
// Vector shifts promote their scalar inputs to vector type. | // Vector shifts promote their scalar inputs to vector type. | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
if (LangOpts.OpenCL) | if (LangOpts.OpenCL) | ||||
return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); | return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); | ||||
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); | if (LangOpts.ZVector) { | ||||
// The shift operators for the z vector extensions work basically | |||||
// like OpenCL shifts, except that neither the LHS nor the RHS is | |||||
// allowed to be a "vector bool". | |||||
if (auto LHSVecType = LHS.get()->getType()->getAs<VectorType>()) | |||||
if (LHSVecType->getVectorKind() == VectorType::AltiVecBool) | |||||
return InvalidOperands(Loc, LHS, RHS); | |||||
if (auto RHSVecType = RHS.get()->getType()->getAs<VectorType>()) | |||||
if (RHSVecType->getVectorKind() == VectorType::AltiVecBool) | |||||
return InvalidOperands(Loc, LHS, RHS); | |||||
return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); | |||||
} | |||||
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, | |||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/false); | |||||
} | } | ||||
// Shifts don't perform usual arithmetic conversions, they just do integer | // Shifts don't perform usual arithmetic conversions, they just do integer | ||||
// promotions on each operand. C99 6.5.7p3 | // promotions on each operand. C99 6.5.7p3 | ||||
// For the LHS, do usual unary conversions, but then reset them away | // For the LHS, do usual unary conversions, but then reset them away | ||||
// if this is a compound assignment. | // if this is a compound assignment. | ||||
ExprResult OldLHS = LHS; | ExprResult OldLHS = LHS; | ||||
▲ Show 20 Lines • Show All 757 Lines • ▼ Show 20 Lines | |||||
/// operates on extended vector types. Instead of producing an IntTy result, | /// operates on extended vector types. Instead of producing an IntTy result, | ||||
/// like a scalar comparison, a vector comparison produces a vector of integer | /// like a scalar comparison, a vector comparison produces a vector of integer | ||||
/// types. | /// types. | ||||
QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, | QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, | ||||
SourceLocation Loc, | SourceLocation Loc, | ||||
bool IsRelational) { | bool IsRelational) { | ||||
// Check to make sure we're operating on vectors of the same type and width, | // Check to make sure we're operating on vectors of the same type and width, | ||||
// Allowing one side to be a scalar of element type. | // Allowing one side to be a scalar of element type. | ||||
QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false); | QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false, | ||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/getLangOpts().ZVector); | |||||
if (vType.isNull()) | if (vType.isNull()) | ||||
return vType; | return vType; | ||||
QualType LHSType = LHS.get()->getType(); | QualType LHSType = LHS.get()->getType(); | ||||
// If AltiVec, the comparison results in a numeric type, i.e. | // If AltiVec, the comparison results in a numeric type, i.e. | ||||
// bool for C++, int for C | // bool for C++, int for C | ||||
if (vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector) | if (getLangOpts().AltiVec && | ||||
vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector) | |||||
return Context.getLogicalOperationType(); | return Context.getLogicalOperationType(); | ||||
// For non-floating point types, check for self-comparisons of the form | // For non-floating point types, check for self-comparisons of the form | ||||
// x == x, x != x, x < x, etc. These always evaluate to a constant, and | // x == x, x != x, x < x, etc. These always evaluate to a constant, and | ||||
// often indicate logic errors in the program. | // often indicate logic errors in the program. | ||||
if (!LHSType->hasFloatingRepresentation() && | if (!LHSType->hasFloatingRepresentation() && | ||||
ActiveTemplateInstantiations.empty()) { | ActiveTemplateInstantiations.empty()) { | ||||
if (DeclRefExpr* DRL | if (DeclRefExpr* DRL | ||||
Show All 17 Lines | QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, | ||||
// Return a signed type for the vector. | // Return a signed type for the vector. | ||||
return GetSignedVectorType(LHSType); | return GetSignedVectorType(LHSType); | ||||
} | } | ||||
QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, | QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, | ||||
SourceLocation Loc) { | SourceLocation Loc) { | ||||
// Ensure that either both operands are of the same vector type, or | // Ensure that either both operands are of the same vector type, or | ||||
// one operand is of a vector type and the other is of its element type. | // one operand is of a vector type and the other is of its element type. | ||||
QualType vType = CheckVectorOperands(LHS, RHS, Loc, false); | QualType vType = CheckVectorOperands(LHS, RHS, Loc, false, | ||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/false); | |||||
if (vType.isNull()) | if (vType.isNull()) | ||||
return InvalidOperands(Loc, LHS, RHS); | return InvalidOperands(Loc, LHS, RHS); | ||||
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && | if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && | ||||
vType->hasFloatingRepresentation()) | vType->hasFloatingRepresentation()) | ||||
return InvalidOperands(Loc, LHS, RHS); | return InvalidOperands(Loc, LHS, RHS); | ||||
return GetSignedVectorType(LHS.get()->getType()); | return GetSignedVectorType(LHS.get()->getType()); | ||||
} | } | ||||
inline QualType Sema::CheckBitwiseOperands( | inline QualType Sema::CheckBitwiseOperands( | ||||
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { | ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { | ||||
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); | ||||
if (LHS.get()->getType()->isVectorType() || | if (LHS.get()->getType()->isVectorType() || | ||||
RHS.get()->getType()->isVectorType()) { | RHS.get()->getType()->isVectorType()) { | ||||
if (LHS.get()->getType()->hasIntegerRepresentation() && | if (LHS.get()->getType()->hasIntegerRepresentation() && | ||||
RHS.get()->getType()->hasIntegerRepresentation()) | RHS.get()->getType()->hasIntegerRepresentation()) | ||||
return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); | return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, | ||||
/*AllowBothBool*/true, | |||||
/*AllowBoolConversions*/getLangOpts().ZVector); | |||||
return InvalidOperands(Loc, LHS, RHS); | return InvalidOperands(Loc, LHS, RHS); | ||||
} | } | ||||
ExprResult LHSResult = LHS, RHSResult = RHS; | ExprResult LHSResult = LHS, RHSResult = RHS; | ||||
QualType compType = UsualArithmeticConversions(LHSResult, RHSResult, | QualType compType = UsualArithmeticConversions(LHSResult, RHSResult, | ||||
IsCompAssign); | IsCompAssign); | ||||
if (LHSResult.isInvalid() || RHSResult.isInvalid()) | if (LHSResult.isInvalid() || RHSResult.isInvalid()) | ||||
return QualType(); | return QualType(); | ||||
▲ Show 20 Lines • Show All 597 Lines • ▼ Show 20 Lines | S.Diag(OpLoc, diag::ext_integer_increment_complex) | ||||
<< ResType << Op->getSourceRange(); | << ResType << Op->getSourceRange(); | ||||
} else if (ResType->isPlaceholderType()) { | } else if (ResType->isPlaceholderType()) { | ||||
ExprResult PR = S.CheckPlaceholderExpr(Op); | ExprResult PR = S.CheckPlaceholderExpr(Op); | ||||
if (PR.isInvalid()) return QualType(); | if (PR.isInvalid()) return QualType(); | ||||
return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc, | return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc, | ||||
IsInc, IsPrefix); | IsInc, IsPrefix); | ||||
} else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { | } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { | ||||
// OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) | // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) | ||||
} else if (S.getLangOpts().ZVector && ResType->isVectorType() && | |||||
(ResType->getAs<VectorType>()->getVectorKind() != | |||||
VectorType::AltiVecBool)) { | |||||
// The z vector extensions allow ++ and -- for non-bool vectors. | |||||
} else if(S.getLangOpts().OpenCL && ResType->isVectorType() && | } else if(S.getLangOpts().OpenCL && ResType->isVectorType() && | ||||
ResType->getAs<VectorType>()->getElementType()->isIntegerType()) { | ResType->getAs<VectorType>()->getElementType()->isIntegerType()) { | ||||
// OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types. | // OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types. | ||||
} else { | } else { | ||||
S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement) | S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement) | ||||
<< ResType << int(IsInc) << Op->getSourceRange(); | << ResType << int(IsInc) << Op->getSourceRange(); | ||||
return QualType(); | return QualType(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,064 Lines • ▼ Show 20 Lines | ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, | ||||
} | } | ||||
case UO_Plus: | case UO_Plus: | ||||
case UO_Minus: | case UO_Minus: | ||||
Input = UsualUnaryConversions(Input.get()); | Input = UsualUnaryConversions(Input.get()); | ||||
if (Input.isInvalid()) return ExprError(); | if (Input.isInvalid()) return ExprError(); | ||||
resultType = Input.get()->getType(); | resultType = Input.get()->getType(); | ||||
if (resultType->isDependentType()) | if (resultType->isDependentType()) | ||||
break; | break; | ||||
if (resultType->isArithmeticType() || // C99 6.5.3.3p1 | if (resultType->isArithmeticType()) // C99 6.5.3.3p1 | ||||
resultType->isVectorType()) | break; | ||||
else if (resultType->isVectorType() && | |||||
// The z vector extensions don't allow + or - with bool vectors. | |||||
(!Context.getLangOpts().ZVector || | |||||
resultType->getAs<VectorType>()->getVectorKind() != | |||||
VectorType::AltiVecBool)) | |||||
break; | break; | ||||
else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6 | else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6 | ||||
Opc == UO_Plus && | Opc == UO_Plus && | ||||
resultType->isPointerType()) | resultType->isPointerType()) | ||||
break; | break; | ||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) | return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) | ||||
<< resultType << Input.get()->getSourceRange()); | << resultType << Input.get()->getSourceRange()); | ||||
▲ Show 20 Lines • Show All 3,708 Lines • Show Last 20 Lines |
It'd be better to phrase this as a positive language mode check than a negative one (that is, AllowbothBool = getLangOpts().Altivec) -- generally, where possible, we should aim for LangOptions values to enable features rather than disable them.