Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -168,6 +168,7 @@ mutable llvm::FoldingSet DependentAddressSpaceTypes; mutable llvm::FoldingSet VectorTypes; + mutable llvm::FoldingSet DependentVectorTypes; mutable llvm::FoldingSet FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet FunctionProtoTypes; @@ -1321,6 +1322,11 @@ /// \pre \p VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; + /// Return the unique reference to the type for a dependently sized vector of + /// the specified element type. + QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr, + SourceLocation AttrLoc, + VectorType::VectorKind VecKind) const; /// Return the unique reference to an extended vector type /// of the specified element type and size. Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -993,6 +993,12 @@ TRY_TO(TraverseType(T->getPointeeType())); }) +DEF_TRAVERSE_TYPE(DependentVectorType, { + if (T->getSizeExpr()) + TRY_TO(TraverseStmt(T->getSizeExpr())); + TRY_TO(TraverseType(T->getElementType())); +}) + DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { if (T->getSizeExpr()) TRY_TO(TraverseStmt(T->getSizeExpr())); @@ -1221,6 +1227,12 @@ TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); }) +DEF_TRAVERSE_TYPELOC(DependentVectorType, { + if (TL.getTypePtr()->getSizeExpr()) + TRY_TO(TraverseStmt(const_cast(TL.getTypePtr()->getSizeExpr()))); + TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); +}) + // FIXME: size and attributes // FIXME: base VectorTypeLoc is unfinished DEF_TRAVERSE_TYPELOC(ExtVectorType, { Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1590,6 +1590,7 @@ class VectorTypeBitfields { friend class VectorType; + friend class DependentVectorType; unsigned : NumTypeBits; @@ -3079,6 +3080,52 @@ } }; +/// Represents a vector type where either the type or size is dependent. +//// +/// For example: +/// \code +/// template +/// class vector { +/// typedef T __attribute__((vector_size(Size))) type; +/// } +/// \endcode +class DependentVectorType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + + const ASTContext &Context; + QualType ElementType; + Expr *SizeExpr; + SourceLocation Loc; + + DependentVectorType(const ASTContext &Context, QualType ElementType, + QualType CanonType, Expr *SizeExpr, + SourceLocation Loc, VectorType::VectorKind vecKind); + +public: + const Expr *getSizeExpr() const { return SizeExpr; } + Expr *getSizeExpr() { return SizeExpr; } + QualType getElementType() const { return ElementType; } + SourceLocation getAttributeLoc() const { return Loc; } + VectorType::VectorKind getVectorKind() const { + return VectorType::VectorKind(VectorTypeBits.VecKind); + } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentVector; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType ElementType, const Expr *SizeExpr, + VectorType::VectorKind VecKind); +}; + /// ExtVectorType - Extended vector type. This type is created using /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This Index: include/clang/AST/TypeLoc.h =================================================================== --- include/clang/AST/TypeLoc.h +++ include/clang/AST/TypeLoc.h @@ -1798,6 +1798,13 @@ VectorType> { }; +// FIXME: size expression and attribute locations (or keyword if we +// ever fully support altivec syntax). +class DependentVectorTypeLoc + : public InheritingConcreteTypeLoc {}; + // FIXME: size expression and attribute locations. class ExtVectorTypeLoc : public InheritingConcreteTypeLoc(T1); + const auto *Vec2 = cast(T2); + if (Vec1->getVectorKind() != Vec2->getVectorKind()) + return false; + if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(), + Vec2->getSizeExpr())) + return false; + if (!IsStructurallyEquivalent(Context, Vec1->getElementType(), + Vec2->getElementType())) + return false; + break; + } + case Type::Vector: case Type::ExtVector: { const auto *Vec1 = cast(T1); Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -539,7 +539,9 @@ void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType, const FunctionDecl *FD = nullptr); void mangleNeonVectorType(const VectorType *T); + void mangleNeonVectorType(const DependentVectorType *T); void mangleAArch64NeonVectorType(const VectorType *T); + void mangleAArch64NeonVectorType(const DependentVectorType *T); void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); void mangleMemberExprBase(const Expr *base, bool isArrow); @@ -1930,6 +1932,7 @@ case Type::VariableArray: case Type::DependentSizedArray: case Type::DependentAddressSpace: + case Type::DependentVector: case Type::DependentSizedExtVector: case Type::Vector: case Type::ExtVector: @@ -3000,6 +3003,14 @@ Out << BaseName << EltName; } +void CXXNameMangler::mangleNeonVectorType(const DependentVectorType *T) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, + "cannot mangle this dependent neon vector type yet"); + Diags.Report(T->getAttributeLoc(), DiagID); +} + static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) { switch (EltType->getKind()) { case BuiltinType::SChar: @@ -3067,6 +3078,13 @@ ("__" + EltName + "x" + Twine(T->getNumElements()) + "_t").str(); Out << TypeName.length() << TypeName; } +void CXXNameMangler::mangleAArch64NeonVectorType(const DependentVectorType *T) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, + "cannot mangle this dependent neon vector type yet"); + Diags.Report(T->getAttributeLoc(), DiagID); +} // GNU extension: vector types // ::= @@ -3097,6 +3115,32 @@ else mangleType(T->getElementType()); } + +void CXXNameMangler::mangleType(const DependentVectorType *T) { + if ((T->getVectorKind() == VectorType::NeonVector || + T->getVectorKind() == VectorType::NeonPolyVector)) { + llvm::Triple Target = getASTContext().getTargetInfo().getTriple(); + llvm::Triple::ArchType Arch = + getASTContext().getTargetInfo().getTriple().getArch(); + if ((Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be) && + !Target.isOSDarwin()) + mangleAArch64NeonVectorType(T); + else + mangleNeonVectorType(T); + return; + } + + Out << "Dv"; + mangleExpression(T->getSizeExpr()); + Out << '_'; + if (T->getVectorKind() == VectorType::AltiVecPixel) + Out << 'p'; + else if (T->getVectorKind() == VectorType::AltiVecBool) + Out << 'b'; + else + mangleType(T->getElementType()); +} + void CXXNameMangler::mangleType(const ExtVectorType *T) { mangleType(static_cast(T)); } Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -2514,6 +2514,16 @@ Qualifiers Quals, SourceRange Range) { mangleType(static_cast(T), Quals, Range); } + +void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T, + Qualifiers, SourceRange Range) { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, + "cannot mangle this dependent-sized vector type yet"); + Diags.Report(Range.getBegin(), DiagID) << Range; +} + void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T, Qualifiers, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -177,6 +177,27 @@ E->Profile(ID, Context, true); } +DependentVectorType::DependentVectorType( + const ASTContext &Context, QualType ElementType, QualType CanonType, + Expr *SizeExpr, SourceLocation Loc, VectorType::VectorKind VecKind) + : Type(DependentVector, CanonType, /*Dependent=*/true, + /*InstantiationDependent=*/true, + ElementType->isVariablyModifiedType(), + ElementType->containsUnexpandedParameterPack() || + (SizeExpr && SizeExpr->containsUnexpandedParameterPack())), + Context(Context), ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) { + VectorTypeBits.VecKind = VecKind; +} + +void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID, + const ASTContext &Context, + QualType ElementType, const Expr *SizeExpr, + VectorType::VectorKind VecKind) { + ID.AddPointer(ElementType.getAsOpaquePtr()); + ID.AddInteger(VecKind); + SizeExpr->Profile(ID, Context, true); +} + DependentSizedExtVectorType::DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, @@ -3783,6 +3804,7 @@ case Type::IncompleteArray: case Type::VariableArray: case Type::DependentSizedArray: + case Type::DependentVector: case Type::DependentSizedExtVector: case Type::Vector: case Type::ExtVector: Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -242,6 +242,7 @@ case Type::RValueReference: case Type::MemberPointer: case Type::DependentAddressSpace: + case Type::DependentVector: case Type::DependentSizedExtVector: case Type::Vector: case Type::ExtVector: @@ -640,7 +641,55 @@ void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) { printAfter(T->getElementType(), OS); -} +} + +void TypePrinter::printDependentVectorBefore( + const DependentVectorType *T, raw_ostream &OS) { + switch (T->getVectorKind()) { + case VectorType::AltiVecPixel: + OS << "__vector __pixel "; + break; + case VectorType::AltiVecBool: + OS << "__vector __bool "; + printBefore(T->getElementType(), OS); + break; + case VectorType::AltiVecVector: + OS << "__vector "; + printBefore(T->getElementType(), OS); + break; + case VectorType::NeonVector: + OS << "__attribute__((neon_vector_type("; + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << "))) "; + printBefore(T->getElementType(), OS); + break; + case VectorType::NeonPolyVector: + OS << "__attribute__((neon_polyvector_type("; + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << "))) "; + printBefore(T->getElementType(), OS); + break; + case VectorType::GenericVector: { + // FIXME: We prefer to print the size directly here, but have no way + // to get the size of the type. + OS << "__attribute__((__vector_size__("; + if (T->getSizeExpr()) + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << " * sizeof("; + print(T->getElementType(), OS, StringRef()); + OS << ")))) "; + printBefore(T->getElementType(), OS); + break; + } + } +} + +void TypePrinter::printDependentVectorAfter( + const DependentVectorType *T, raw_ostream &OS) { + printAfter(T->getElementType(), OS); +} void TypePrinter::printExtVectorBefore(const ExtVectorType *T, raw_ostream &OS) { Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -5341,6 +5341,11 @@ return Visit(T->getElementType()); } +bool UnnamedLocalNoLinkageFinder::VisitDependentVectorType( + const DependentVectorType *T) { + return Visit(T->getElementType()); +} + bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) { return Visit(T->getElementType()); } Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -1870,6 +1870,55 @@ return Sema::TDK_NonDeducedMismatch; } + case Type::DependentVector: { + const auto *VectorParam = cast(Param); + + if (const auto *VectorArg = dyn_cast(Arg)) { + // Perform deduction on the element types. + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VectorParam->getElementType(), + VectorArg->getElementType(), Info, Deduced, TDF)) + return Result; + + // Perform deduction on the vector size, if we can. + NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( + Info, const_cast(VectorParam->getSizeExpr())); + if (!NTTP) + return Sema::TDK_Success; + + llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); + ArgSize = VectorArg->getNumElements(); + // Note that we use the "array bound" rules here; just like in that + // case, we don't have any particular type for the vector size, but + // we can provide one if necessary. + return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize, + S.Context.UnsignedIntTy, true, + Info, Deduced); + } + + if (const auto *VectorArg = dyn_cast(Arg)) { + // Perform deduction on the element types. + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VectorParam->getElementType(), + VectorArg->getElementType(), Info, Deduced, TDF)) + return Result; + + // Perform deduction on the vector size, if we can. + NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( + Info, const_cast(VectorParam->getSizeExpr())); + if (!NTTP) + return Sema::TDK_Success; + + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, + const_cast(VectorArg->getSizeExpr()), Info, Deduced); + } + + return Sema::TDK_NonDeducedMismatch; + } + // (clang extension) // // T __attribute__(((ext_vector_type(N)))) @@ -5264,6 +5313,14 @@ OnlyDeduced, Depth, Used); break; + case Type::DependentVector: { + const auto *VecType = cast(T); + MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced, + Depth, Used); + MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced, Depth, + Used); + break; + } case Type::DependentSizedExtVector: { const DependentSizedExtVectorType *VecType = cast(T); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -2243,6 +2243,58 @@ return T; } +QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr, + SourceLocation AttrLoc) { + // The base type must be integer (not Boolean or enumeration) or float, and + // can't already be a vector. + if (!CurType->isDependentType() && + (!CurType->isBuiltinType() || CurType->isBooleanType() || + (!CurType->isIntegerType() && !CurType->isRealFloatingType()))) { + Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << CurType; + return QualType(); + } + + if (SizeExpr->isTypeDependent() || SizeExpr->isValueDependent()) + return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, + VectorType::GenericVector); + + llvm::APSInt VecSize(32); + if (!SizeExpr->isIntegerConstantExpr(VecSize, Context)) { + Diag(AttrLoc, diag::err_attribute_argument_type) + << "vector_size" << AANT_ArgumentIntegerConstant + << SizeExpr->getSourceRange(); + return QualType(); + } + + if (CurType->isDependentType()) + return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, + VectorType::GenericVector); + + unsigned VectorSize = static_cast(VecSize.getZExtValue() * 8); + unsigned TypeSize = static_cast(Context.getTypeSize(CurType)); + + if (VectorSize == 0) { + Diag(AttrLoc, diag::err_attribute_zero_size) << SizeExpr->getSourceRange(); + return QualType(); + } + + // vecSize is specified in bytes - convert to bits. + if (VectorSize % TypeSize) { + Diag(AttrLoc, diag::err_attribute_invalid_size) + << SizeExpr->getSourceRange(); + return QualType(); + } + + if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) { + Diag(AttrLoc, diag::err_attribute_size_too_large) + << SizeExpr->getSourceRange(); + return QualType(); + } + + return Context.getVectorType(CurType, VectorSize / TypeSize, + VectorType::GenericVector); +} + /// Build an ext-vector type. /// /// Run the required checks for the extended vector type. @@ -6857,52 +6909,30 @@ Attr.setInvalid(); return; } - Expr *sizeExpr = static_cast(Attr.getArgAsExpr(0)); - llvm::APSInt vecSize(32); - if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() || - !sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) - << Attr.getName() << AANT_ArgumentIntegerConstant - << sizeExpr->getSourceRange(); - Attr.setInvalid(); - return; - } - // The base type must be integer (not Boolean or enumeration) or float, and - // can't already be a vector. - if (!CurType->isBuiltinType() || CurType->isBooleanType() || - (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { - S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; - Attr.setInvalid(); - return; - } - unsigned typeSize = static_cast(S.Context.getTypeSize(CurType)); - // vecSize is specified in bytes - convert to bits. - unsigned vectorSize = static_cast(vecSize.getZExtValue() * 8); - // the vector size needs to be an integral multiple of the type size. - if (vectorSize % typeSize) { - S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) - << sizeExpr->getSourceRange(); - Attr.setInvalid(); - return; - } - if (VectorType::isVectorSizeTooLarge(vectorSize / typeSize)) { - S.Diag(Attr.getLoc(), diag::err_attribute_size_too_large) - << sizeExpr->getSourceRange(); - Attr.setInvalid(); - return; - } - if (vectorSize == 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) - << sizeExpr->getSourceRange(); - Attr.setInvalid(); - return; + Expr *SizeExpr; + // Special case where the argument is a template id. + if (Attr.isArgIdent(0)) { + CXXScopeSpec SS; + SourceLocation TemplateKWLoc; + UnqualifiedId Id; + Id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc()); + + ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc, + Id, false, false); + + if (Size.isInvalid()) + return; + SizeExpr = Size.get(); + } else { + SizeExpr = Attr.getArgAsExpr(0); } - // Success! Instantiate the vector type, the number of elements is > 0, and - // not required to be a power of 2, unlike GCC. - CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, - VectorType::GenericVector); + QualType T = S.BuildVectorType(CurType, SizeExpr, Attr.getLoc()); + if (!T.isNull()) + CurType = T; + else + Attr.setInvalid(); } /// Process the OpenCL-like ext_vector_type attribute when it occurs on Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -818,6 +818,15 @@ QualType RebuildVectorType(QualType ElementType, unsigned NumElements, VectorType::VectorKind VecKind); + /// Build a new potentially dependently-sized extended vector type + /// given the element type and number of elements. + /// + /// By default, performs semantic analysis when building the vector type. + /// Subclasses may override this routine to provide different behavior. + QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr, + SourceLocation AttributeLoc, + VectorType::VectorKind); + /// Build a new extended vector type given the element type and /// number of elements. /// @@ -4750,6 +4759,45 @@ return Result; } +template +QualType TreeTransform::TransformDependentVectorType( + TypeLocBuilder &TLB, DependentVectorTypeLoc TL) { + const DependentVectorType *T = TL.getTypePtr(); + QualType ElementType = getDerived().TransformType(T->getElementType()); + if (ElementType.isNull()) + return QualType(); + + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); + + ExprResult Size = + getDerived().TransformExpr(const_cast(T->getSizeExpr())); + Size = SemaRef.ActOnConstantExpression(Size); + if (Size.isInvalid()) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() || + Size.get() != T->getSizeExpr()) { + Result = getDerived().RebuildDependentVectorType( + ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind()); + if (Result.isNull()) + return QualType(); + } + + // Result might be dependent or not. + if (isa(Result)) { + DependentVectorTypeLoc NewTL = + TLB.push(Result); + NewTL.setNameLoc(TL.getNameLoc()); + } else { + VectorTypeLoc NewTL = TLB.push(Result); + NewTL.setNameLoc(TL.getNameLoc()); + } + + return Result; +} + template QualType TreeTransform::TransformDependentSizedExtVectorType( TypeLocBuilder &TLB, @@ -12381,6 +12429,13 @@ return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind); } +template +QualType TreeTransform::RebuildDependentVectorType( + QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc, + VectorType::VectorKind VecKind) { + return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc); +} + template QualType TreeTransform::RebuildExtVectorType(QualType ElementType, unsigned NumElements, Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -6369,6 +6369,17 @@ return Context.getPipeType(ElementType, ReadOnly); } + case TYPE_DEPENDENT_SIZED_VECTOR: { + unsigned Idx = 0; + QualType ElementType = readType(*Loc.F, Record, Idx); + Expr *SizeExpr = ReadExpr(*Loc.F); + SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx); + unsigned VecKind = Record[Idx]; + + return Context.getDependentVectorType(ElementType, SizeExpr, AttrLoc, + (VectorType::VectorKind)VecKind); + } + case TYPE_DEPENDENT_SIZED_EXT_VECTOR: { unsigned Idx = 0; @@ -6549,6 +6560,11 @@ TL.setNameLoc(ReadSourceLocation()); } +void TypeLocReader::VisitDependentVectorTypeLoc( + DependentVectorTypeLoc TL) { + TL.setNameLoc(ReadSourceLocation()); +} + void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -455,6 +455,14 @@ Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR; } +void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) { + Record.AddTypeRef(T->getElementType()); + Record.AddStmt(const_cast(T->getSizeExpr())); + Record.AddSourceLocation(T->getAttributeLoc()); + Record.push_back(T->getVectorKind()); + Code = TYPE_DEPENDENT_SIZED_VECTOR; +} + void ASTTypeWriter::VisitDependentAddressSpaceType( const DependentAddressSpaceType *T) { @@ -676,6 +684,11 @@ Record.AddSourceLocation(TL.getNameLoc()); } +void TypeLocWriter::VisitDependentVectorTypeLoc( + DependentVectorTypeLoc TL) { + Record.AddSourceLocation(TL.getNameLoc()); +} + void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); } Index: test/SemaCXX/vector.cpp =================================================================== --- test/SemaCXX/vector.cpp +++ test/SemaCXX/vector.cpp @@ -291,3 +291,46 @@ // PR12649 typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}} + +namespace Templates { +template +struct TemplateVectorType { + typedef Elt __attribute__((__vector_size__(Size))) type; +}; + +template +struct PR15730 { + typedef T __attribute__((vector_size(N * sizeof(T)))) type; + typedef T __attribute__((vector_size(8192))) type2; + typedef T __attribute__((vector_size(3))) type3; +}; + +void Init() { + const TemplateVectorType::type Works = {}; + const TemplateVectorType::type Works2 = {}; + // expected-error@298 {{invalid vector element type 'bool'}} + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type NoBool; + // expected-error@298 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}} + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type NoComplex; + // expected-error@298 {{vector size not an integral multiple of component size}} + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type BadSize; + // expected-error@298 {{vector size too large}} + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type TooLarge; + // expected-error@298 {{zero vector size}} + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type Zero; + + // expected-error@304 {{vector size too large}} + // expected-error@305 {{vector size not an integral multiple of component size}} + // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, int>' requested here}} + const PR15730<8, int>::type PR15730_1 = {}; + // expected-error@304 {{vector size too large}} + // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, char>' requested here}} + const PR15730<8, char>::type2 PR15730_2 = {}; +} + +} // namespace Templates Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1772,6 +1772,7 @@ DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType) DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType) DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type) +DEFAULT_TYPELOC_IMPL(DependentVector, Type) DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type) DEFAULT_TYPELOC_IMPL(Vector, Type) DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)