Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -6990,10 +6990,11 @@ return visitArray(Val, Ty, Offset); case APValue::Struct: return visitRecord(Val, Ty, Offset); + case APValue::Vector: + return visitVector(Val, Ty, Offset); case APValue::ComplexInt: case APValue::ComplexFloat: - case APValue::Vector: case APValue::FixedPoint: // FIXME: We should support these. @@ -7080,6 +7081,21 @@ return true; } + bool visitVector(const APValue &Val, QualType Ty, CharUnits Offset) { + const auto *VT = Ty->castAs(); + + CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(VT->getElementType()); + unsigned VectorLength = Val.getVectorLength(); + // Visit each of the vector elements + for (unsigned I = 0; I != VectorLength; ++I) { + const APValue &SubObj = Val.getVectorElt(I); + if (!visit(SubObj, VT->getElementType(), Offset + I * ElemWidth)) + return false; + } + + return true; + } + bool visitInt(const APSInt &Val, QualType Ty, CharUnits Offset) { APSInt AdjustedVal = Val; unsigned Width = AdjustedVal.getBitWidth(); @@ -7289,6 +7305,22 @@ return ArrayValue; } + std::optional visit(const VectorType *Ty, CharUnits Offset) { + size_t NumElements = Ty->getNumElements(); + CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->getElementType()); + + SmallVector Elts; + for (size_t I = 0; I != NumElements; ++I) { + std::optional ElementValue = + visitType(Ty->getElementType(), Offset + I * ElementWidth); + if (!ElementValue) + return std::nullopt; + Elts.push_back(std::move(*ElementValue)); + } + + return APValue(Elts.data(), Elts.size()); + } + std::optional visit(const Type *Ty, CharUnits Offset) { return unsupportedType(QualType(Ty, 0)); } Index: clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp =================================================================== --- clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp @@ -463,3 +463,19 @@ static_assert(round_trip<__int128_t>(34.0L)); #endif } + +namespace test_vector { + +typedef unsigned uint2 __attribute__((vector_size(2 * sizeof(unsigned)))); +typedef char byte8 __attribute__((vector_size(sizeof(unsigned long long)))); + +constexpr uint2 test_vector = { 0x0C05FEFE, 0xCAFEBABE }; + +static_assert(bit_cast(test_vector) == (LITTLE_END + ? 0xCAFEBABE0C05FEFE + : 0x0C05FEFECAFEBABE), ""); + +static_assert(round_trip(0xCAFEBABE0C05FEFEULL), ""); +static_assert(round_trip(0xCAFEBABE0C05FEFEULL), ""); + +}