forked from OSchip/llvm-project
[NFC] Switch CodeGenFunction to use value init instead of member init lists
The member init list for the sole constructor for CodeGenFunction has gotten out of hand, so this patch moves the non-parameter-dependent initializations into the member value inits. llvm-svn: 336726
This commit is contained in:
parent
79d55d30c3
commit
7b8c12e7cc
|
@ -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.
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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 sizeis 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, 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
|
||||
|
|
|
@ -1798,6 +1798,12 @@ 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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1371,6 +1371,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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
@ -3312,6 +3313,44 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
|
|||
Types.push_back(New);
|
||||
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.
|
||||
|
|
|
@ -405,6 +405,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);
|
||||
|
|
|
@ -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,11 @@ void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
|
|||
Out << BaseName << EltName;
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleNeonVectorType(const DependentVectorType *T) {
|
||||
llvm_unreachable(
|
||||
"Mangling for Dependent Sized Neon Vector not yet implemented");
|
||||
}
|
||||
|
||||
static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) {
|
||||
switch (EltType->getKind()) {
|
||||
case BuiltinType::SChar:
|
||||
|
@ -3067,6 +3075,10 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
|
|||
("__" + EltName + "x" + Twine(T->getNumElements()) + "_t").str();
|
||||
Out << TypeName.length() << TypeName;
|
||||
}
|
||||
void CXXNameMangler::mangleAArch64NeonVectorType(const DependentVectorType *T) {
|
||||
llvm_unreachable(
|
||||
"Mangling for Dependent Sized AArch64 Neon Vector not yet implemented");
|
||||
}
|
||||
|
||||
// GNU extension: vector types
|
||||
// <type> ::= <vector-type>
|
||||
|
@ -3097,6 +3109,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));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -177,6 +177,28 @@ 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, Expr *SizeExpr,
|
||||
VectorType::VectorKind VecKind) {
|
||||
ID.AddPointer(ElementType.getAsOpaquePtr());
|
||||
SizeExpr->Profile(ID, Context, true);
|
||||
}
|
||||
|
||||
DependentSizedExtVectorType::DependentSizedExtVectorType(const
|
||||
ASTContext &Context,
|
||||
QualType ElementType,
|
||||
|
@ -3783,6 +3805,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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -65,25 +65,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
|
|||
: CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
|
||||
Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
|
||||
CGBuilderInserterTy(this)),
|
||||
CurFn(nullptr), ReturnValue(Address::invalid()),
|
||||
CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
|
||||
IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
|
||||
SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
|
||||
BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
|
||||
NormalCleanupDest(Address::invalid()), NextCleanupDestIndex(1),
|
||||
FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
|
||||
EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
|
||||
DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
|
||||
PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
|
||||
CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
|
||||
NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
|
||||
CXXABIThisValue(nullptr), CXXThisValue(nullptr),
|
||||
CXXStructorImplicitParamDecl(nullptr),
|
||||
CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
|
||||
CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
|
||||
TerminateHandler(nullptr), TrapBB(nullptr), LargestVectorWidth(0),
|
||||
ShouldEmitLifetimeMarkers(
|
||||
shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
|
||||
SanOpts(CGM.getLangOpts().Sanitize), DebugInfo(CGM.getModuleDebugInfo()),
|
||||
PGO(cgm), ShouldEmitLifetimeMarkers(shouldEmitLifetimeMarkers(
|
||||
CGM.getCodeGenOpts(), CGM.getLangOpts())) {
|
||||
if (!suppressNewContext)
|
||||
CGM.getCXXABI().getMangleContext().startNewFunction();
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ public:
|
|||
const Decl *CurCodeDecl;
|
||||
const CGFunctionInfo *CurFnInfo;
|
||||
QualType FnRetTy;
|
||||
llvm::Function *CurFn;
|
||||
llvm::Function *CurFn = nullptr;
|
||||
|
||||
// Holds coroutine data if the current function is a coroutine. We use a
|
||||
// wrapper to manage its lifetime, so that we don't have to define CGCoroData
|
||||
|
@ -242,7 +242,7 @@ public:
|
|||
|
||||
/// ReturnValue - The temporary alloca to hold the return
|
||||
/// value. This is invalid iff the function has no return value.
|
||||
Address ReturnValue;
|
||||
Address ReturnValue = Address::invalid();
|
||||
|
||||
/// Return true if a label was seen in the current scope.
|
||||
bool hasLabelBeenSeenInCurrentScope() const {
|
||||
|
@ -321,7 +321,7 @@ public:
|
|||
/// Captured 'this' type.
|
||||
FieldDecl *CXXThisFieldDecl;
|
||||
};
|
||||
CGCapturedStmtInfo *CapturedStmtInfo;
|
||||
CGCapturedStmtInfo *CapturedStmtInfo = nullptr;
|
||||
|
||||
/// RAII for correct setting/restoring of CapturedStmtInfo.
|
||||
class CGCapturedStmtRAII {
|
||||
|
@ -366,7 +366,7 @@ public:
|
|||
SanitizerSet SanOpts;
|
||||
|
||||
/// True if CodeGen currently emits code implementing sanitizer checks.
|
||||
bool IsSanitizerScope;
|
||||
bool IsSanitizerScope = false;
|
||||
|
||||
/// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
|
||||
class SanitizerScope {
|
||||
|
@ -378,26 +378,26 @@ public:
|
|||
|
||||
/// In C++, whether we are code generating a thunk. This controls whether we
|
||||
/// should emit cleanups.
|
||||
bool CurFuncIsThunk;
|
||||
bool CurFuncIsThunk = false;
|
||||
|
||||
/// In ARC, whether we should autorelease the return value.
|
||||
bool AutoreleaseResult;
|
||||
bool AutoreleaseResult = false;
|
||||
|
||||
/// Whether we processed a Microsoft-style asm block during CodeGen. These can
|
||||
/// potentially set the return value.
|
||||
bool SawAsmBlock;
|
||||
bool SawAsmBlock = false;
|
||||
|
||||
const FunctionDecl *CurSEHParent = nullptr;
|
||||
|
||||
/// True if the current function is an outlined SEH helper. This can be a
|
||||
/// finally block or filter expression.
|
||||
bool IsOutlinedSEHHelper;
|
||||
bool IsOutlinedSEHHelper = false;
|
||||
|
||||
const CodeGen::CGBlockInfo *BlockInfo;
|
||||
llvm::Value *BlockPointer;
|
||||
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
|
||||
llvm::Value *BlockPointer = nullptr;
|
||||
|
||||
llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
|
||||
FieldDecl *LambdaThisCaptureField;
|
||||
FieldDecl *LambdaThisCaptureField = nullptr;
|
||||
|
||||
/// A mapping from NRVO variables to the flags used to indicate
|
||||
/// when the NRVO has been applied to this variable.
|
||||
|
@ -434,23 +434,23 @@ public:
|
|||
};
|
||||
|
||||
/// i32s containing the indexes of the cleanup destinations.
|
||||
Address NormalCleanupDest;
|
||||
Address NormalCleanupDest = Address::invalid();
|
||||
|
||||
unsigned NextCleanupDestIndex;
|
||||
unsigned NextCleanupDestIndex = 1;
|
||||
|
||||
/// FirstBlockInfo - The head of a singly-linked-list of block layouts.
|
||||
CGBlockInfo *FirstBlockInfo;
|
||||
CGBlockInfo *FirstBlockInfo = nullptr;
|
||||
|
||||
/// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
|
||||
llvm::BasicBlock *EHResumeBlock;
|
||||
llvm::BasicBlock *EHResumeBlock = nullptr;
|
||||
|
||||
/// The exception slot. All landing pads write the current exception pointer
|
||||
/// into this alloca.
|
||||
llvm::Value *ExceptionSlot;
|
||||
llvm::Value *ExceptionSlot = nullptr;
|
||||
|
||||
/// The selector slot. Under the MandatoryCleanup model, all landing pads
|
||||
/// write the current selector value into this alloca.
|
||||
llvm::AllocaInst *EHSelectorSlot;
|
||||
llvm::AllocaInst *EHSelectorSlot = nullptr;
|
||||
|
||||
/// A stack of exception code slots. Entering an __except block pushes a slot
|
||||
/// on the stack and leaving pops one. The __exception_code() intrinsic loads
|
||||
|
@ -1087,17 +1087,17 @@ public:
|
|||
|
||||
private:
|
||||
CGDebugInfo *DebugInfo;
|
||||
bool DisableDebugInfo;
|
||||
bool DisableDebugInfo = false;
|
||||
|
||||
/// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
|
||||
/// calling llvm.stacksave for multiple VLAs in the same scope.
|
||||
bool DidCallStackSave;
|
||||
bool DidCallStackSave = false;
|
||||
|
||||
/// IndirectBranch - The first time an indirect goto is seen we create a block
|
||||
/// with an indirect branch. Every time we see the address of a label taken,
|
||||
/// we add the label to the indirect goto. Every subsequent indirect goto is
|
||||
/// codegen'd as a jump to the IndirectBranch's basic block.
|
||||
llvm::IndirectBrInst *IndirectBranch;
|
||||
llvm::IndirectBrInst *IndirectBranch = nullptr;
|
||||
|
||||
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
|
||||
/// decls.
|
||||
|
@ -1247,13 +1247,13 @@ private:
|
|||
|
||||
/// SwitchInsn - This is nearest current switch instruction. It is null if
|
||||
/// current context is not in a switch.
|
||||
llvm::SwitchInst *SwitchInsn;
|
||||
llvm::SwitchInst *SwitchInsn = nullptr;
|
||||
/// The branch weights of SwitchInsn when doing instrumentation based PGO.
|
||||
SmallVector<uint64_t, 16> *SwitchWeights;
|
||||
SmallVector<uint64_t, 16> *SwitchWeights = nullptr;
|
||||
|
||||
/// CaseRangeBlock - This block holds if condition check for last case
|
||||
/// statement range in current switch instruction.
|
||||
llvm::BasicBlock *CaseRangeBlock;
|
||||
llvm::BasicBlock *CaseRangeBlock = nullptr;
|
||||
|
||||
/// OpaqueLValues - Keeps track of the current set of opaque value
|
||||
/// expressions.
|
||||
|
@ -1270,13 +1270,13 @@ private:
|
|||
|
||||
/// A block containing a single 'unreachable' instruction. Created
|
||||
/// lazily by getUnreachableBlock().
|
||||
llvm::BasicBlock *UnreachableBlock;
|
||||
llvm::BasicBlock *UnreachableBlock = nullptr;
|
||||
|
||||
/// Counts of the number return expressions in the function.
|
||||
unsigned NumReturnExprs;
|
||||
unsigned NumReturnExprs = 0;
|
||||
|
||||
/// Count the number of simple (constant) return expressions in the function.
|
||||
unsigned NumSimpleReturnExprs;
|
||||
unsigned NumSimpleReturnExprs = 0;
|
||||
|
||||
/// The last regular (non-return) debug location (breakpoint) in the function.
|
||||
SourceLocation LastStopPoint;
|
||||
|
@ -1396,9 +1396,9 @@ public:
|
|||
private:
|
||||
/// CXXThisDecl - When generating code for a C++ member function,
|
||||
/// this will hold the implicit 'this' declaration.
|
||||
ImplicitParamDecl *CXXABIThisDecl;
|
||||
llvm::Value *CXXABIThisValue;
|
||||
llvm::Value *CXXThisValue;
|
||||
ImplicitParamDecl *CXXABIThisDecl = nullptr;
|
||||
llvm::Value *CXXABIThisValue = nullptr;
|
||||
llvm::Value *CXXThisValue = nullptr;
|
||||
CharUnits CXXABIThisAlignment;
|
||||
CharUnits CXXThisAlignment;
|
||||
|
||||
|
@ -1416,16 +1416,16 @@ private:
|
|||
|
||||
/// CXXStructorImplicitParamDecl - When generating code for a constructor or
|
||||
/// destructor, this will hold the implicit argument (e.g. VTT).
|
||||
ImplicitParamDecl *CXXStructorImplicitParamDecl;
|
||||
llvm::Value *CXXStructorImplicitParamValue;
|
||||
ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr;
|
||||
llvm::Value *CXXStructorImplicitParamValue = nullptr;
|
||||
|
||||
/// OutermostConditional - Points to the outermost active
|
||||
/// conditional control. This is used so that we know if a
|
||||
/// temporary should be destroyed conditionally.
|
||||
ConditionalEvaluation *OutermostConditional;
|
||||
ConditionalEvaluation *OutermostConditional = nullptr;
|
||||
|
||||
/// The current lexical scope.
|
||||
LexicalScope *CurLexicalScope;
|
||||
LexicalScope *CurLexicalScope = nullptr;
|
||||
|
||||
/// The current source location that should be used for exception
|
||||
/// handling code.
|
||||
|
@ -1456,16 +1456,16 @@ private:
|
|||
CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>());
|
||||
}
|
||||
|
||||
llvm::BasicBlock *TerminateLandingPad;
|
||||
llvm::BasicBlock *TerminateHandler;
|
||||
llvm::BasicBlock *TrapBB;
|
||||
llvm::BasicBlock *TerminateLandingPad = nullptr;
|
||||
llvm::BasicBlock *TerminateHandler = nullptr;
|
||||
llvm::BasicBlock *TrapBB = nullptr;
|
||||
|
||||
/// Terminate funclets keyed by parent funclet pad.
|
||||
llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
|
||||
|
||||
/// Largest vector width used in ths function. Will be used to create a
|
||||
/// function attribute.
|
||||
unsigned LargestVectorWidth;
|
||||
unsigned LargestVectorWidth = 0;
|
||||
|
||||
/// True if we need emit the life-time markers.
|
||||
const bool ShouldEmitLifetimeMarkers;
|
||||
|
|
|
@ -5346,6 +5346,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());
|
||||
}
|
||||
|
|
|
@ -1837,6 +1837,55 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
|
|||
return Sema::TDK_NonDeducedMismatch;
|
||||
}
|
||||
|
||||
case Type::DependentVector: {
|
||||
const DependentVectorType *VectorParam = cast<DependentVectorType>(Param);
|
||||
|
||||
if (const VectorType *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.IntTy, true, Info,
|
||||
Deduced);
|
||||
}
|
||||
|
||||
if (const DependentVectorType *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))))
|
||||
|
@ -5227,6 +5276,14 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
|
|||
OnlyDeduced, Depth, Used);
|
||||
break;
|
||||
|
||||
case Type::DependentVector: {
|
||||
const DependentVectorType *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);
|
||||
|
|
|
@ -2294,6 +2294,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.
|
||||
|
@ -6929,52 +6981,30 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &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
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
@ -4746,6 +4755,43 @@ 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,
|
||||
|
@ -12377,6 +12423,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,
|
||||
|
|
|
@ -6371,6 +6371,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;
|
||||
|
||||
|
@ -6551,6 +6562,10 @@ void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
|
|||
TL.setNameLoc(ReadSourceLocation());
|
||||
}
|
||||
|
||||
void TypeLocReader::VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
|
||||
TL.setNameLoc(ReadSourceLocation());
|
||||
}
|
||||
|
||||
void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
|
||||
TL.setNameLoc(ReadSourceLocation());
|
||||
}
|
||||
|
|
|
@ -455,6 +455,14 @@ ASTTypeWriter::VisitDependentSizedExtVectorType(
|
|||
Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
|
||||
}
|
||||
|
||||
void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) {
|
||||
Record.AddTypeRef(T->getElementType());
|
||||
Record.AddStmt(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,10 @@ 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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue