@@ -221,6 +221,12 @@ namespace {
221221 ArraySize = 2;
222222 MostDerivedLength = I + 1;
223223 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;
224230 } else if (const FieldDecl *FD = getAsField(Path[I])) {
225231 Type = FD->getType();
226232 ArraySize = 0;
@@ -437,6 +443,15 @@ namespace {
437443 MostDerivedArraySize = 2;
438444 MostDerivedPathLength = Entries.size();
439445 }
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+ }
440455 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441456 void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442457 const APSInt &N);
@@ -1732,6 +1747,10 @@ namespace {
17321747 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
17331748 Designator.addComplexUnchecked(EltTy, Imag);
17341749 }
1750+ void addVector(EvalInfo &Info, const Expr *E, const VectorType *VecTy) {
1751+ if (checkSubobject(Info, E, CSK_ArrayIndex))
1752+ Designator.addVectorUnchecked(VecTy);
1753+ }
17351754 void clearIsNullPointer() {
17361755 IsNullPtr = false;
17371756 }
@@ -1890,6 +1909,8 @@ static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
18901909static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
18911910 EvalInfo &Info);
18921911
1912+ static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info);
1913+
18931914//===----------------------------------------------------------------------===//
18941915// Misc utilities
18951916//===----------------------------------------------------------------------===//
@@ -3278,6 +3299,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
32783299 return true;
32793300}
32803301
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+
32813315/// Try to evaluate the initializer for a variable declaration.
32823316///
32833317/// \param Info Information about the ongoing evaluation.
@@ -3718,7 +3752,8 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
37183752 }
37193753
37203754 // 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()))) {
37223757 // Accesses to volatile objects are prohibited.
37233758 if (ObjType.isVolatileQualified() && isFormalAccess(handler.AccessKind)) {
37243759 if (Info.getLangOpts().CPlusPlus) {
@@ -3823,6 +3858,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
38233858 return handler.found(Index ? O->getComplexFloatImag()
38243859 : O->getComplexFloatReal(), ObjType);
38253860 }
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);
38263865 } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
38273866 if (Field->isMutable() &&
38283867 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8756,14 +8795,28 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
87568795}
87578796
87588797bool 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())
87628800 return Error(E);
87638801
87648802 APSInt Index;
87658803 bool Success = true;
87668804
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+
87678820 // C++17's rules require us to evaluate the LHS first, regardless of which
87688821 // side is the base.
87698822 for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
0 commit comments