[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