aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2018-07-13 19:46:04 +0000
committerErich Keane <erich.keane@intel.com>2018-07-13 19:46:04 +0000
commit12e2fde436d38782477f681dbf3fc83b8095e188 (patch)
tree86442dc143d91a91cbeaddee88bbe3fa6a8c0bc5
parentd119a80874f84aed19417020a5ab04d4568f1743 (diff)
PR15730/PR16986 Allow dependently typed vector_size types.
As listed in the above PRs, vector_size doesn't allow dependent types/values. This patch introduces a new DependentVectorType to handle a VectorType that has a dependent size or type. In the future, ALL the vector-types should be able to create one of these to handle dependent types/sizes as well. For example, DependentSizedExtVectorType could likely be switched to just use this instead, though that is left as an exercise for the future. Differential Revision: https://reviews.llvm.org/D49045 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337036 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h6
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h12
-rw-r--r--include/clang/AST/Type.h46
-rw-r--r--include/clang/AST/TypeLoc.h7
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/Sema/Sema.h1
-rw-r--r--include/clang/Serialization/ASTBitCodes.h85
-rw-r--r--lib/AST/ASTContext.cpp40
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp16
-rw-r--r--lib/AST/ItaniumMangle.cpp44
-rw-r--r--lib/AST/MicrosoftMangle.cpp10
-rw-r--r--lib/AST/Type.cpp22
-rw-r--r--lib/AST/TypePrinter.cpp51
-rw-r--r--lib/Lex/LiteralSupport.cpp2
-rw-r--r--lib/Sema/SemaTemplate.cpp5
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp56
-rw-r--r--lib/Sema/SemaType.cpp116
-rw-r--r--lib/Sema/TreeTransform.h54
-rw-r--r--lib/Serialization/ASTReader.cpp16
-rw-r--r--lib/Serialization/ASTWriter.cpp13
-rw-r--r--test/SemaCXX/vector.cpp43
-rw-r--r--tools/libclang/CIndex.cpp1
22 files changed, 560 insertions, 87 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index ddfbdc2472..8d3cf760a5 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -168,6 +168,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentAddressSpaceType>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
+ mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
@@ -1321,6 +1322,11 @@ public:
/// \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.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 3e6090d312..0d2b670507 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -993,6 +993,12 @@ DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
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 @@ DEF_TRAVERSE_TYPELOC(VectorType, {
TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
})
+DEF_TRAVERSE_TYPELOC(DependentVectorType, {
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index dbe96a00f5..b21d9f4127 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1590,6 +1590,7 @@ protected:
class VectorTypeBitfields {
friend class VectorType;
+ friend class DependentVectorType;
unsigned : NumTypeBits;
@@ -3079,6 +3080,51 @@ public:
}
};
+/// Represents a vector type where either the type or size is dependent.
+////
+/// For example:
+/// \code
+/// template<typename T, int Size>
+/// 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:
+ Expr *getSizeExpr() const { 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
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 53d5a1a627..73909e50ff 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1798,6 +1798,13 @@ class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
VectorType> {
};
+// FIXME: size expression and attribute locations (or keyword if we
+// ever fully support altivec syntax).
+class DependentVectorTypeLoc
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DependentVectorTypeLoc,
+ DependentVectorType> {};
+
// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 66697fa0d0..8638f94bda 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -75,6 +75,7 @@ DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type)
DEPENDENT_TYPE(DependentAddressSpace, Type)
TYPE(Vector, Type)
+DEPENDENT_TYPE(DependentVector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e4e1467b12..a818125760 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1377,6 +1377,7 @@ public:
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
SourceRange Brackets, DeclarationName Entity);
+ QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 82bb1f5fa1..76bc818557 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1032,133 +1032,133 @@ namespace serialization {
/// AST. Note that DeclCode values share this code space.
enum TypeCode {
/// An ExtQualType record.
- TYPE_EXT_QUAL = 1,
+ TYPE_EXT_QUAL = 1,
/// A ComplexType record.
- TYPE_COMPLEX = 3,
+ TYPE_COMPLEX = 3,
/// A PointerType record.
- TYPE_POINTER = 4,
+ TYPE_POINTER = 4,
/// A BlockPointerType record.
- TYPE_BLOCK_POINTER = 5,
+ TYPE_BLOCK_POINTER = 5,
/// An LValueReferenceType record.
- TYPE_LVALUE_REFERENCE = 6,
+ TYPE_LVALUE_REFERENCE = 6,
/// An RValueReferenceType record.
- TYPE_RVALUE_REFERENCE = 7,
+ TYPE_RVALUE_REFERENCE = 7,
/// A MemberPointerType record.
- TYPE_MEMBER_POINTER = 8,
+ TYPE_MEMBER_POINTER = 8,
/// A ConstantArrayType record.
- TYPE_CONSTANT_ARRAY = 9,
+ TYPE_CONSTANT_ARRAY = 9,
/// An IncompleteArrayType record.
- TYPE_INCOMPLETE_ARRAY = 10,
+ TYPE_INCOMPLETE_ARRAY = 10,
/// A VariableArrayType record.
- TYPE_VARIABLE_ARRAY = 11,
+ TYPE_VARIABLE_ARRAY = 11,
/// A VectorType record.
- TYPE_VECTOR = 12,
+ TYPE_VECTOR = 12,
/// An ExtVectorType record.
- TYPE_EXT_VECTOR = 13,
+ TYPE_EXT_VECTOR = 13,
/// A FunctionNoProtoType record.
- TYPE_FUNCTION_NO_PROTO = 14,
+ TYPE_FUNCTION_NO_PROTO = 14,
/// A FunctionProtoType record.
- TYPE_FUNCTION_PROTO = 15,
+ TYPE_FUNCTION_PROTO = 15,
/// A TypedefType record.
- TYPE_TYPEDEF = 16,
+ TYPE_TYPEDEF = 16,
/// A TypeOfExprType record.
- TYPE_TYPEOF_EXPR = 17,
+ TYPE_TYPEOF_EXPR = 17,
/// A TypeOfType record.
- TYPE_TYPEOF = 18,
+ TYPE_TYPEOF = 18,
/// A RecordType record.
- TYPE_RECORD = 19,
+ TYPE_RECORD = 19,
/// An EnumType record.
- TYPE_ENUM = 20,
+ TYPE_ENUM = 20,
/// An ObjCInterfaceType record.
- TYPE_OBJC_INTERFACE = 21,
+ TYPE_OBJC_INTERFACE = 21,
/// An ObjCObjectPointerType record.
- TYPE_OBJC_OBJECT_POINTER = 22,
+ TYPE_OBJC_OBJECT_POINTER = 22,
/// a DecltypeType record.
- TYPE_DECLTYPE = 23,
+ TYPE_DECLTYPE = 23,
/// An ElaboratedType record.
- TYPE_ELABORATED = 24,
+ TYPE_ELABORATED = 24,
/// A SubstTemplateTypeParmType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
/// An UnresolvedUsingType record.
- TYPE_UNRESOLVED_USING = 26,
+ TYPE_UNRESOLVED_USING = 26,
/// An InjectedClassNameType record.
- TYPE_INJECTED_CLASS_NAME = 27,
+ TYPE_INJECTED_CLASS_NAME = 27,
/// An ObjCObjectType record.
- TYPE_OBJC_OBJECT = 28,
+ TYPE_OBJC_OBJECT = 28,
/// An TemplateTypeParmType record.
- TYPE_TEMPLATE_TYPE_PARM = 29,
+ TYPE_TEMPLATE_TYPE_PARM = 29,
/// An TemplateSpecializationType record.
- TYPE_TEMPLATE_SPECIALIZATION = 30,
+ TYPE_TEMPLATE_SPECIALIZATION = 30,
/// A DependentNameType record.
- TYPE_DEPENDENT_NAME = 31,
+ TYPE_DEPENDENT_NAME = 31,
/// A DependentTemplateSpecializationType record.
TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
/// A DependentSizedArrayType record.
- TYPE_DEPENDENT_SIZED_ARRAY = 33,
+ TYPE_DEPENDENT_SIZED_ARRAY = 33,
/// A ParenType record.
- TYPE_PAREN = 34,
+ TYPE_PAREN = 34,
/// A PackExpansionType record.
- TYPE_PACK_EXPANSION = 35,
+ TYPE_PACK_EXPANSION = 35,
/// An AttributedType record.
- TYPE_ATTRIBUTED = 36,
+ TYPE_ATTRIBUTED = 36,
/// A SubstTemplateTypeParmPackType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
/// A AutoType record.
- TYPE_AUTO = 38,
+ TYPE_AUTO = 38,
/// A UnaryTransformType record.
- TYPE_UNARY_TRANSFORM = 39,
+ TYPE_UNARY_TRANSFORM = 39,
/// An AtomicType record.
- TYPE_ATOMIC = 40,
+ TYPE_ATOMIC = 40,
/// A DecayedType record.
- TYPE_DECAYED = 41,
+ TYPE_DECAYED = 41,
/// An AdjustedType record.
- TYPE_ADJUSTED = 42,
+ TYPE_ADJUSTED = 42,
/// A PipeType record.
- TYPE_PIPE = 43,
+ TYPE_PIPE = 43,
/// An ObjCTypeParamType record.
- TYPE_OBJC_TYPE_PARAM = 44,
+ TYPE_OBJC_TYPE_PARAM = 44,
/// A DeducedTemplateSpecializationType record.
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
@@ -1167,7 +1167,10 @@ namespace serialization {
TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46,
/// A DependentAddressSpaceType record.
- TYPE_DEPENDENT_ADDRESS_SPACE = 47
+ TYPE_DEPENDENT_ADDRESS_SPACE = 47,
+
+ /// A dependentSizedVectorType record.
+ TYPE_DEPENDENT_SIZED_VECTOR = 48
};
/// The type IDs for special types constructed by semantic
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 832f3a2e7a..d6bc9c0c71 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3035,6 +3035,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Builtin:
case Type::Complex:
case Type::Vector:
+ case Type::DependentVector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
case Type::DependentAddressSpace:
@@ -3313,6 +3314,45 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
return QualType(New, 0);
}
+QualType
+ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,
+ SourceLocation AttrLoc,
+ VectorType::VectorKind VecKind) const {
+ llvm::FoldingSetNodeID ID;
+ DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,
+ VecKind);
+ void *InsertPos = nullptr;
+ DependentVectorType *Canon =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ DependentVectorType *New;
+
+ if (Canon) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);
+ } else {
+ QualType CanonVecTy = getCanonicalType(VecType);
+ if (CanonVecTy == VecType) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(), SizeExpr, AttrLoc, VecKind);
+
+ DependentVectorType *CanonCheck =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!CanonCheck &&
+ "Dependent-sized vector_size canonical type broken");
+ (void)CanonCheck;
+ DependentVectorTypes.InsertNode(New, InsertPos);
+ } else {
+ QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
+ SourceLocation());
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, Canon, SizeExpr, AttrLoc, VecKind);
+ }
+ }
+
+ Types.push_back(New);
+ return QualType(New, 0);
+}
+
/// getExtVectorType - Return the unique reference to an extended vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index d158680a69..77e0d9e61b 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -51,7 +51,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
/// Determine structural equivalence of two expressions.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
- Expr *E1, Expr *E2) {
+ const Expr *E1, const Expr *E2) {
if (!E1 || !E2)
return E1 == E2;
@@ -408,6 +408,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
+ case Type::DependentVector: {
+ const auto *Vec1 = cast<DependentVectorType>(T1);
+ const auto *Vec2 = cast<DependentVectorType>(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<VectorType>(T1);
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index d8c435991e..6f7efcbe1b 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -539,7 +539,9 @@ private:
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 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
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 @@ void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
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 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
("__" + 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
// <type> ::= <vector-type>
@@ -3097,6 +3115,32 @@ void CXXNameMangler::mangleType(const VectorType *T) {
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<const VectorType*>(T));
}
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 32c26270ec..f9cd24ce9a 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -2514,6 +2514,16 @@ void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
Qualifiers Quals, SourceRange Range) {
mangleType(static_cast<const VectorType *>(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();
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index ddb45868ec..cd30bc16d0 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -177,6 +177,27 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
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 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::IncompleteArray:
case Type::VariableArray:
case Type::DependentSizedArray:
+ case Type::DependentVector:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index b424b24574..c5e2244e26 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -242,6 +242,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
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::printVectorBefore(const VectorType *T, raw_ostream &OS) {
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) {
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index e414f85e02..c1be3b2a97 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -734,7 +734,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (!hadError && saw_fixed_point_suffix) {
assert(isFract || isAccum);
- assert(radix == 16 || radix == 10);
+ //assert(radix == 16 || radix == 10);
}
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index e78fd438dc..c1d8c24796 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -5341,6 +5341,11 @@ bool UnnamedLocalNoLinkageFinder::VisitVectorType(const VectorType* T) {
return Visit(T->getElementType());
}
+bool UnnamedLocalNoLinkageFinder::VisitDependentVectorType(
+ const DependentVectorType *T) {
+ return Visit(T->getElementType());
+}
+
bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) {
return Visit(T->getElementType());
}
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 3a480628a7..51d2bae08c 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1870,6 +1870,54 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
return Sema::TDK_NonDeducedMismatch;
}
+ case Type::DependentVector: {
+ const auto *VectorParam = cast<DependentVectorType>(Param);
+
+ if (const auto *VectorArg = dyn_cast<VectorType>(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, 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<DependentVectorType>(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, VectorParam->getSizeExpr());
+ if (!NTTP)
+ return Sema::TDK_Success;
+
+ return DeduceNonTypeTemplateArgument(
+ S, TemplateParams, NTTP, VectorArg->getSizeExpr(), Info, Deduced);
+ }
+
+ return Sema::TDK_NonDeducedMismatch;
+ }
+
// (clang extension)
//
// T __attribute__(((ext_vector_type(N))))
@@ -5264,6 +5312,14 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
OnlyDeduced, Depth, Used);
break;
+ case Type::DependentVector: {
+ const auto *VecType = cast<DependentVectorType>(T);
+ MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced,
+ Depth, Used);
+ MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced, Depth,
+ Used);
+ break;
+ }
case Type::DependentSizedExtVector: {
const DependentSizedExtVectorType *VecType
= cast<DependentSizedExtVectorType>(T);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 641a2f5f06..0736fabac3 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2243,6 +2243,58 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
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<unsigned>(VecSize.getZExtValue() * 8);
+ unsigned TypeSize = static_cast<unsigned>(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 @@ static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr,
Attr.setInvalid();
return;
}
- Expr *sizeExpr = static_cast<Expr *>(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<unsigned>(S.Context.getTypeSize(CurType));
- // vecSize is specified in bytes - convert to bits.
- unsigned vectorSize = static_cast<unsigned>(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
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 6ee5eca75c..5ed92aea32 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -818,6 +818,15 @@ public:
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,44 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
return Result;
}
+template <typename Derived>
+QualType TreeTransform<Derived>::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(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<DependentVectorType>(Result)) {
+ DependentVectorTypeLoc NewTL =
+ TLB.push<DependentVectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ } else {
+ VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ }
+
+ return Result;
+}
+
template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
TypeLocBuilder &TLB,
@@ -12381,6 +12428,13 @@ TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
}
+template <typename Derived>
+QualType TreeTransform<Derived>::RebuildDependentVectorType(
+ QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
+ VectorType::VectorKind VecKind) {
+ return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
+}
+
template<typename Derived>
QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
unsigned NumElements,
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 3277243667..19b5af38df 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6369,6 +6369,17 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
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 @@ void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
+void TypeLocReader::VisitDependentVectorTypeLoc(
+ DependentVectorTypeLoc TL) {
+ TL.setNameLoc(ReadSourceLocation());
+}
+
void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index bc569d17f2..1a8d806e9d 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -455,6 +455,14 @@ ASTTypeWriter::VisitDependentSizedExtVectorType(
Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
}
+void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) {
+ Record.AddTypeRef(T->getElementType());
+ Record.AddStmt(const_cast<Expr*>(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 @@ void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+void TypeLocWriter::VisitDependentVectorTypeLoc(
+ DependentVectorTypeLoc TL) {
+ Record.AddSourceLocation(TL.getNameLoc());
+}
+
void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp
index 8fe24a32c8..56a8a6db5b 100644
--- a/test/SemaCXX/vector.cpp
+++ b/test/SemaCXX/vector.cpp
@@ -291,3 +291,46 @@ const int &reference_to_vec_element = vi4(1).x;
// PR12649
typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}}
+
+namespace Templates {
+template <typename Elt, unsigned Size>
+struct TemplateVectorType {
+ typedef Elt __attribute__((__vector_size__(Size))) type;
+};
+
+template <int N, typename T>
+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<float, 32>::type Works = {};
+ const TemplateVectorType<int, 32>::type Works2 = {};
+ // expected-error@298 {{invalid vector element type 'bool'}}
+ // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<bool, 32>' requested here}}
+ const TemplateVectorType<bool, 32>::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<int __attribute__((ext_vector_type(4))), 32>' requested here}}
+ const TemplateVectorType<vi4, 32>::type NoComplex;
+ // expected-error@298 {{vector size not an integral multiple of component size}}
+ // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 33>' requested here}}
+ const TemplateVectorType<int, 33>::type BadSize;
+ // expected-error@298 {{vector size too large}}
+ // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 8192>' requested here}}
+ const TemplateVectorType<int, 8192>::type TooLarge;
+ // expected-error@298 {{zero vector size}}
+ // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 0>' requested here}}
+ const TemplateVectorType<int, 0>::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
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index b61dff3238..499d9abf9a 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1772,6 +1772,7 @@ DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
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)