[cfe-commits] r73641 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/AST/TypeNodes.def lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaType.cpp test/SemaTemplate/ext-vector-type.cpp
Douglas Gregor
dgregor at apple.com
Wed Jun 17 14:52:00 PDT 2009
Author: dgregor
Date: Wed Jun 17 16:51:59 2009
New Revision: 73641
URL: http://llvm.org/viewvc/llvm-project?rev=73641&view=rev
Log:
Support dependent extended vector types and template instantiation
thereof. Patch by Anders Johnsen!
Added:
cfe/trunk/test/SemaTemplate/ext-vector-type.cpp
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeNodes.def
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jun 17 16:51:59 2009
@@ -71,6 +71,7 @@
llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
std::vector<VariableArrayType*> VariableArrayTypes;
std::vector<DependentSizedArrayType*> DependentSizedArrayTypes;
+ std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes;
llvm::FoldingSet<VectorType> VectorTypes;
llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
@@ -277,6 +278,14 @@
/// type.
QualType getExtVectorType(QualType VectorType, unsigned NumElts);
+ /// getDependentSizedExtVectorType - Returns a non-unique reference to
+ /// the type for a dependently-sized vector of the specified element
+ /// type. FIXME: We will need these to be uniqued, or at least
+ /// comparable, at some point.
+ QualType getDependentSizedExtVectorType(QualType VectorType,
+ Expr *SizeExpr,
+ SourceLocation AttrLoc);
+
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
QualType getFunctionNoProtoType(QualType ResultTy);
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jun 17 16:51:59 2009
@@ -992,6 +992,41 @@
}
};
+/// DependentSizedExtVectorType - This type represent an ext vectory type
+/// where either the type or size is dependent. For example:
+/// @code
+/// template<typename T, int Size>
+/// class vector {
+/// typedef T __attribute__((ext_vector_type(Size))) type;
+/// }
+/// @endcode
+class DependentSizedExtVectorType : public Type {
+ Expr *SizeExpr;
+ /// ElementType - The element type of the array.
+ QualType ElementType;
+ SourceLocation loc;
+
+ DependentSizedExtVectorType(QualType ElementType, QualType can,
+ Expr *SizeExpr, SourceLocation loc)
+ : Type (DependentSizedExtVector, can, true),
+ SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {}
+ friend class ASTContext;
+ virtual void Destroy(ASTContext& C);
+
+public:
+ Expr *getSizeExpr() const { return SizeExpr; }
+ QualType getElementType() const { return ElementType; }
+ SourceLocation getAttributeLoc() const { return loc; }
+
+ virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const;
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentSizedExtVector;
+ }
+ static bool classof(const DependentSizedExtVectorType *) { return true; }
+};
+
+
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
/// bytes. Since the constructor takes the number of vector elements, the
@@ -1783,7 +1818,7 @@
static bool classof(const ObjCQualifiedIdType *) { return true; }
};
-
+
// Inline function definitions.
/// getUnqualifiedType - Return the type without any qualifiers.
Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Wed Jun 17 16:51:59 2009
@@ -60,6 +60,7 @@
TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
+DEPENDENT_TYPE(DependentSizedExtVector, Type)
TYPE(Vector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jun 17 16:51:59 2009
@@ -1269,6 +1269,18 @@
return QualType(New, 0);
}
+QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
+ Expr *SizeExpr,
+ SourceLocation AttrLoc) {
+ DependentSizedExtVectorType *New =
+ new (*this,8) DependentSizedExtVectorType(vecType, QualType(),
+ SizeExpr, AttrLoc);
+
+ DependentSizedExtVectorTypes.push_back(New);
+ Types.push_back(New);
+ return QualType(New, 0);
+}
+
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) {
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Jun 17 16:51:59 2009
@@ -50,6 +50,13 @@
C.Deallocate(this);
}
+void DependentSizedExtVectorType::Destroy(ASTContext& C) {
+ if (SizeExpr)
+ SizeExpr->Destroy(C);
+ this->~DependentSizedExtVectorType();
+ C.Deallocate(this);
+}
+
/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
@@ -1356,6 +1363,19 @@
getElementType().getAsStringInternal(S, Policy);
}
+void DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
+ getElementType().getAsStringInternal(S, Policy);
+
+ S += " __attribute__((ext_vector_ type(";
+ if (getSizeExpr()) {
+ std::string SStr;
+ llvm::raw_string_ostream s(SStr);
+ getSizeExpr()->printPretty(s, 0, Policy);
+ S += s.str();
+ }
+ S += ")))";
+}
+
void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
// FIXME: We prefer to print the size directly here, but have no way
// to get the size of the type.
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Jun 17 16:51:59 2009
@@ -359,6 +359,8 @@
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
+ QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
+ SourceLocation AttrLoc);
QualType BuildFunctionType(QualType T,
QualType *ParamTypes, unsigned NumParamTypes,
bool Variadic, unsigned Quals,
@@ -1116,8 +1118,8 @@
// More parsing and symbol table subroutines.
// Decl attributes - this routine is the top level dispatcher.
- void ProcessDeclAttributes(Decl *D, const Declarator &PD);
- void ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList);
+ void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
+ void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList);
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 17 16:51:59 2009
@@ -1615,7 +1615,7 @@
NewTD->setInvalidDecl();
// Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewTD, D);
+ ProcessDeclAttributes(S, NewTD, D);
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
@@ -1801,7 +1801,7 @@
NewVD->setLexicalDeclContext(CurContext);
// Handle attributes prior to checking for duplicates in MergeVarDecl
- ProcessDeclAttributes(NewVD, D);
+ ProcessDeclAttributes(S, NewVD, D);
// Handle GNU asm-label extension (encoded as an attribute).
if (Expr *E = (Expr*) D.getAsmLabel()) {
@@ -2298,7 +2298,7 @@
// (for example to check for conflicts, etc).
// FIXME: This needs to happen before we merge declarations. Then,
// let attribute merging cope with attribute conflicts.
- ProcessDeclAttributes(NewFD, D);
+ ProcessDeclAttributes(S, NewFD, D);
AddKnownFunctionAttributes(NewFD);
if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
@@ -2907,7 +2907,7 @@
if (II)
IdResolver.AddDecl(New);
- ProcessDeclAttributes(New, D);
+ ProcessDeclAttributes(S, New, D);
if (New->hasAttr<BlocksAttr>()) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
@@ -3628,7 +3628,7 @@
New->setInvalidDecl();
if (Attr)
- ProcessDeclAttributeList(New, Attr);
+ ProcessDeclAttributeList(S, New, Attr);
// If we're declaring or defining a tag in function prototype scope
// in C, note that this type can only be used within the function.
@@ -3878,7 +3878,8 @@
// FIXME: We need to pass in the attributes given an AST
// representation, not a parser representation.
if (D)
- ProcessDeclAttributes(NewFD, *D);
+ // FIXME: What to pass instead of TUScope?
+ ProcessDeclAttributes(TUScope, NewFD, *D);
if (T.isObjCGCWeak())
Diag(Loc, diag::warn_attribute_weak_on_field);
@@ -3985,7 +3986,7 @@
}
// Process attributes attached to the ivar.
- ProcessDeclAttributes(NewID, D);
+ ProcessDeclAttributes(S, NewID, D);
if (D.isInvalidType())
NewID->setInvalidDecl();
@@ -4151,7 +4152,7 @@
}
if (Attr)
- ProcessDeclAttributeList(Record, Attr);
+ ProcessDeclAttributeList(S, Record, Attr);
}
EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jun 17 16:51:59 2009
@@ -156,8 +156,8 @@
// least add some helper functions to check most argument patterns (#
// and types of args).
-static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
+ const AttributeList &Attr, Sema &S) {
TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
if (tDecl == 0) {
S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
@@ -165,37 +165,32 @@
}
QualType curType = tDecl->getUnderlyingType();
- // check the attribute arguments.
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
- return;
- }
- Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
- llvm::APSInt vecSize(32);
- if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
- << "ext_vector_type" << sizeExpr->getSourceRange();
- return;
- }
- // unlike gcc's vector_size attribute, we do not allow vectors to be defined
- // in conjunction with complex types (pointers, arrays, functions, etc.).
- if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType;
- return;
+
+ Expr *sizeExpr;
+
+ // Special case where the argument is a template id.
+ if (Attr.getParameterName()) {
+ sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(),
+ Attr.getParameterName(),
+ false, 0, false).takeAs<Expr>();
+ } else {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ return;
+ }
+ sizeExpr = static_cast<Expr *>(Attr.getArg(0));
}
- // unlike gcc's vector_size attribute, the size is specified as the
- // number of elements, not the number of bytes.
- unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
-
- if (vectorSize == 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
- << sizeExpr->getSourceRange();
- return;
+
+ // Instantiate/Install the vector type, and let Sema build the type for us.
+ // This will run the reguired checks.
+ QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
+ if (!T.isNull()) {
+ tDecl->setUnderlyingType(T);
+
+ // Remember this typedef decl, we will need it later for diagnostics.
+ S.ExtVectorDecls.push_back(tDecl);
}
- // Instantiate/Install the vector type, the number of elements is > 0.
- tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
- // Remember this typedef decl, we will need it later for diagnostics.
- S.ExtVectorDecls.push_back(tDecl);
}
@@ -1698,7 +1693,7 @@
/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
/// the attribute applies to decls. If the attribute is a type attribute, just
/// silently ignore it.
-static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
+static void ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr, Sema &S) {
if (Attr.isDeclspecAttribute())
// FIXME: Try to deal with __declspec attributes!
return;
@@ -1721,7 +1716,7 @@
case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
case AttributeList::AT_ext_vector_type:
- HandleExtVectorTypeAttr(D, Attr, S);
+ HandleExtVectorTypeAttr(scope, D, Attr, S);
break;
case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
@@ -1777,9 +1772,9 @@
/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
/// attribute list to the specified decl, ignoring any type attributes.
-void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
+void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
while (AttrList) {
- ProcessDeclAttribute(D, *AttrList, *this);
+ ProcessDeclAttribute(S, D, *AttrList, *this);
AttrList = AttrList->getNext();
}
}
@@ -1787,10 +1782,10 @@
/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
/// it, apply them to D. This is a bit tricky because PD can have attributes
/// specified in many different places, and we need to find and apply them all.
-void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
+void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
// Apply decl attributes from the DeclSpec if present.
if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
- ProcessDeclAttributeList(D, Attrs);
+ ProcessDeclAttributeList(S, D, Attrs);
// Walk the declarator structure, applying decl attributes that were in a type
// position to the decl itself. This handles cases like:
@@ -1798,9 +1793,9 @@
// when X is a decl attribute.
for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
- ProcessDeclAttributeList(D, Attrs);
+ ProcessDeclAttributeList(S, D, Attrs);
// Finally, apply any attributes on the decl itself.
if (const AttributeList *Attrs = PD.getAttributes())
- ProcessDeclAttributeList(D, Attrs);
+ ProcessDeclAttributeList(S, D, Attrs);
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 17 16:51:59 2009
@@ -2671,7 +2671,7 @@
else
CurContext->addDecl(Context, ExDecl);
- ProcessDeclAttributes(ExDecl, D);
+ ProcessDeclAttributes(S, ExDecl, D);
return DeclPtrTy::make(ExDecl);
}
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Jun 17 16:51:59 2009
@@ -116,7 +116,7 @@
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
ClassName, ClassLoc);
if (AttrList)
- ProcessDeclAttributeList(IDecl, AttrList);
+ ProcessDeclAttributeList(TUScope, IDecl, AttrList);
PushOnScopeChains(IDecl, TUScope);
}
@@ -282,7 +282,7 @@
PDecl->setForwardDecl(false);
}
if (AttrList)
- ProcessDeclAttributeList(PDecl, AttrList);
+ ProcessDeclAttributeList(TUScope, PDecl, AttrList);
if (NumProtoRefs) {
/// Check then save referenced protocols.
PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,Context);
@@ -532,7 +532,7 @@
PushOnScopeChains(PDecl, TUScope);
}
if (attrList)
- ProcessDeclAttributeList(PDecl, attrList);
+ ProcessDeclAttributeList(TUScope, PDecl, attrList);
Protocols.push_back(PDecl);
}
@@ -1663,7 +1663,7 @@
CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
// Apply the attributes to the parameter.
- ProcessDeclAttributeList(Param, ArgInfo[i].ArgAttrs);
+ ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
Params.push_back(Param);
}
@@ -1674,7 +1674,7 @@
const ObjCMethodDecl *PrevMethod = 0;
if (AttrList)
- ProcessDeclAttributeList(ObjCMethod, AttrList);
+ ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
// For implementations (which can be very "coarse grain"), we add the
// method now. This allows the AST to implement lookup methods that work
@@ -1877,7 +1877,7 @@
PDecl->setInvalidDecl();
}
- ProcessDeclAttributes(PDecl, FD.D);
+ ProcessDeclAttributes(S, PDecl, FD.D);
// Regardless of setter/getter attribute, we save the default getter/setter
// selector names in anticipation of declaration of setter/getter methods.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jun 17 16:51:59 2009
@@ -5126,7 +5126,7 @@
if (ParamInfo.getNumTypeObjects() == 0
|| ParamInfo.getTypeObject(0).Kind != DeclaratorChunk::Function) {
- ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
+ ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
if (T->isArrayType()) {
@@ -5182,7 +5182,7 @@
CurBlock->TheDecl->setParams(Context, CurBlock->Params.data(),
CurBlock->Params.size());
CurBlock->TheDecl->setIsVariadic(CurBlock->isVariadic);
- ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
+ ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
E = CurBlock->TheDecl->param_end(); AI != E; ++AI)
// If this has an identifier, add it to the scope stack.
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jun 17 16:51:59 2009
@@ -548,7 +548,7 @@
NewClass->startDefinition();
if (Attr)
- ProcessDeclAttributeList(NewClass, Attr);
+ ProcessDeclAttributeList(S, NewClass, Attr);
PushOnScopeChains(NewTemplate, S);
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Jun 17 16:51:59 2009
@@ -802,6 +802,14 @@
Deduced);
break;
+ case Type::DependentSizedExtVector: {
+ const DependentSizedExtVectorType *VecType
+ = cast<DependentSizedExtVectorType>(T.getTypePtr());
+ MarkDeducedTemplateParameters(SemaRef, VecType->getElementType(), Deduced);
+ MarkDeducedTemplateParameters(VecType->getSizeExpr(), Deduced);
+ break;
+ }
+
case Type::FunctionProto: {
const FunctionProtoType *Proto = cast<FunctionProtoType>(T.getTypePtr());
MarkDeducedTemplateParameters(SemaRef, Proto->getResultType(), Deduced);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Jun 17 16:51:59 2009
@@ -431,6 +431,32 @@
}
QualType
+TemplateTypeInstantiator::
+InstantiateDependentSizedExtVectorType(const DependentSizedExtVectorType *T,
+ unsigned Quals) const {
+
+ // Instantiate the element type if needed
+ QualType ElementType = T->getElementType();
+ if (ElementType->isDependentType()) {
+ ElementType = Instantiate(ElementType);
+ if (ElementType.isNull())
+ return QualType();
+ }
+
+ // Instantiate the size expression
+ Expr *SizeExpr = T->getSizeExpr();
+ Sema::OwningExprResult InstantiatedArraySize =
+ SemaRef.InstantiateExpr(SizeExpr, TemplateArgs);
+ if (InstantiatedArraySize.isInvalid())
+ return QualType();
+
+ return SemaRef.BuildExtVectorType(ElementType,
+ SemaRef.Owned(
+ InstantiatedArraySize.takeAs<Expr>()),
+ T->getAttributeLoc());
+}
+
+QualType
TemplateTypeInstantiator::InstantiateVectorType(const VectorType *T,
unsigned Quals) const {
// FIXME: Implement this
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=73641&r1=73640&r2=73641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jun 17 16:51:59 2009
@@ -543,6 +543,48 @@
return T;
}
+
+/// \brief Build an ext-vector type.
+///
+/// Run the required checks for the extended vector type.
+QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
+ SourceLocation AttrLoc) {
+
+ Expr *Arg = (Expr *)ArraySize.get();
+
+ // unlike gcc's vector_size attribute, we do not allow vectors to be defined
+ // in conjunction with complex types (pointers, arrays, functions, etc.).
+ if (!T->isDependentType() &&
+ !T->isIntegerType() && !T->isRealFloatingType()) {
+ Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << T;
+ return QualType();
+ }
+
+ if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+ llvm::APSInt vecSize(32);
+ if (!Arg->isIntegerConstantExpr(vecSize, Context)) {
+ Diag(AttrLoc, diag::err_attribute_argument_not_int)
+ << "ext_vector_type" << Arg->getSourceRange();
+ return QualType();
+ }
+
+ // unlike gcc's vector_size attribute, the size is specified as the
+ // number of elements, not the number of bytes.
+ unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
+
+ if (vectorSize == 0) {
+ Diag(AttrLoc, diag::err_attribute_zero_size)
+ << Arg->getSourceRange();
+ return QualType();
+ }
+
+ if (!T->isDependentType())
+ return Context.getExtVectorType(T, vectorSize);
+ }
+
+ return Context.getDependentSizedExtVectorType(T, ArraySize.takeAs<Expr>(),
+ AttrLoc);
+}
/// \brief Build a function type.
///
Added: cfe/trunk/test/SemaTemplate/ext-vector-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ext-vector-type.cpp?rev=73641&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/ext-vector-type.cpp (added)
+++ cfe/trunk/test/SemaTemplate/ext-vector-type.cpp Wed Jun 17 16:51:59 2009
@@ -0,0 +1,47 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template<typename T, unsigned Length>
+struct make1 {
+ typedef T __attribute__((ext_vector_type(Length))) type;
+};
+
+int test_make1() {
+ make1<int, 5>::type x;
+ x.x = 4;
+}
+
+template<typename T, unsigned Length>
+struct make2 {
+ typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{zero vector size}}
+};
+
+int test_make2() {
+ make2<int, 0> x; // expected-note{{in instantiation of}}
+}
+
+template<typename T, unsigned Length>
+struct make3 {
+ typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type 'struct s'}}
+};
+
+struct s {};
+
+int test_make3() {
+ make3<s, 3>x; // expected-note{{in instantiation of}}
+}
+
+template<typename T, T Length>
+struct make4 {
+ typedef T __attribute__((ext_vector_type(Length))) type;
+};
+
+int test_make4() {
+ make4<int, 4>::type x;
+ x.w = 7;
+}
+
+typedef int* int_ptr;
+template<unsigned Length>
+struct make5 {
+ typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type}}
+};
+
More information about the cfe-commits
mailing list