@@ -221,6 +221,12 @@ namespace {
221
221
ArraySize = 2;
222
222
MostDerivedLength = I + 1;
223
223
IsArray = true;
224
+ } else if (Type->isVectorType()) {
225
+ const VectorType *CT = Type->castAs<VectorType>();
226
+ Type = CT->getElementType();
227
+ ArraySize = CT->getNumElements();
228
+ MostDerivedLength = I + 1;
229
+ IsArray = true;
224
230
} else if (const FieldDecl *FD = getAsField(Path[I])) {
225
231
Type = FD->getType();
226
232
ArraySize = 0;
@@ -437,6 +443,15 @@ namespace {
437
443
MostDerivedArraySize = 2;
438
444
MostDerivedPathLength = Entries.size();
439
445
}
446
+ /// Update this designator to refer to the given vector component.
447
+ void addVectorUnchecked(const VectorType *VecTy) {
448
+ Entries.push_back(PathEntry::ArrayIndex(0));
449
+
450
+ MostDerivedType = VecTy->getElementType();
451
+ MostDerivedIsArrayElement = true;
452
+ MostDerivedArraySize = VecTy->getNumElements();
453
+ MostDerivedPathLength = Entries.size();
454
+ }
440
455
void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441
456
void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442
457
const APSInt &N);
@@ -1732,6 +1747,10 @@ namespace {
1732
1747
if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1733
1748
Designator.addComplexUnchecked(EltTy, Imag);
1734
1749
}
1750
+ void addVector(EvalInfo &Info, const Expr *E, const VectorType *VecTy) {
1751
+ if (checkSubobject(Info, E, CSK_ArrayIndex))
1752
+ Designator.addVectorUnchecked(VecTy);
1753
+ }
1735
1754
void clearIsNullPointer() {
1736
1755
IsNullPtr = false;
1737
1756
}
@@ -1890,6 +1909,8 @@ static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
1890
1909
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
1891
1910
EvalInfo &Info);
1892
1911
1912
+ static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info);
1913
+
1893
1914
//===----------------------------------------------------------------------===//
1894
1915
// Misc utilities
1895
1916
//===----------------------------------------------------------------------===//
@@ -3278,6 +3299,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
3278
3299
return true;
3279
3300
}
3280
3301
3302
+ static bool HandeLValueVectorComponent(EvalInfo &Info, const Expr *E,
3303
+ LValue &LVal, const VectorType *VecTy,
3304
+ APSInt &Adjustment) {
3305
+ LVal.addVector(Info, E, VecTy);
3306
+
3307
+ CharUnits SizeOfComponent;
3308
+ if (!HandleSizeof(Info, E->getExprLoc(), VecTy->getElementType(),
3309
+ SizeOfComponent))
3310
+ return false;
3311
+ LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfComponent);
3312
+ return true;
3313
+ }
3314
+
3281
3315
/// Try to evaluate the initializer for a variable declaration.
3282
3316
///
3283
3317
/// \param Info Information about the ongoing evaluation.
@@ -3718,7 +3752,8 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
3718
3752
}
3719
3753
3720
3754
// If this is our last pass, check that the final object type is OK.
3721
- if (I == N || (I == N - 1 && ObjType->isAnyComplexType())) {
3755
+ if (I == N || (I == N - 1 &&
3756
+ (ObjType->isAnyComplexType() || ObjType->isVectorType()))) {
3722
3757
// Accesses to volatile objects are prohibited.
3723
3758
if (ObjType.isVolatileQualified() && isFormalAccess(handler.AccessKind)) {
3724
3759
if (Info.getLangOpts().CPlusPlus) {
@@ -3823,6 +3858,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
3823
3858
return handler.found(Index ? O->getComplexFloatImag()
3824
3859
: O->getComplexFloatReal(), ObjType);
3825
3860
}
3861
+ } else if (ObjType->isVectorType()) {
3862
+ // Next Subobject is a vector element
3863
+ uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3864
+ O = &O->getVectorElt(Index);
3826
3865
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3827
3866
if (Field->isMutable() &&
3828
3867
!Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8756,14 +8795,28 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
8756
8795
}
8757
8796
8758
8797
bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
8759
- // FIXME: Deal with vectors as array subscript bases.
8760
- if (E->getBase()->getType()->isVectorType() ||
8761
- E->getBase()->getType()->isSveVLSBuiltinType())
8798
+
8799
+ if (E->getBase()->getType()->isSveVLSBuiltinType())
8762
8800
return Error(E);
8763
8801
8764
8802
APSInt Index;
8765
8803
bool Success = true;
8766
8804
8805
+ if (E->getBase()->getType()->isVectorType()) {
8806
+ for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
8807
+ Success = (SubExpr == E->getBase())
8808
+ ? EvaluateLValue(SubExpr, Result, Info, true)
8809
+ : EvaluateInteger(SubExpr, Index, Info);
8810
+ }
8811
+ if (Success) {
8812
+ Success = HandeLValueVectorComponent(
8813
+ Info, E, Result, E->getBase()->getType()->castAs<VectorType>(),
8814
+ Index);
8815
+ return Success;
8816
+ }
8817
+ return false;
8818
+ }
8819
+
8767
8820
// C++17's rules require us to evaluate the LHS first, regardless of which
8768
8821
// side is the base.
8769
8822
for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
0 commit comments