Index: test/Sema/vector-init.c
===================================================================
--- test/Sema/vector-init.c	(revision 90569)
+++ test/Sema/vector-init.c	(working copy)
@@ -16,10 +16,14 @@
 float4 array3[2] = { {1.0, 2.0, 3.0}, 5.0, 6.0, 7.0, 8.0,
                      9.0 }; // expected-warning {{excess elements in array initializer}}
 
+__attribute__((vector_size(16))) float f1(void) {
+  __attribute__((vector_size(16))) float vec = {0.0f, 0.0f, 0.0f};
+  return(vec);
+}
 
-// rdar://6881069
-__attribute__((vector_size(16))) // expected-error {{unsupported type 'float (void)' for vector_size attribute, please use on typedef}}
-float f1(void) {
+__attribute__((vector_size(16))) float f2(
+    __attribute__((vector_size(16))) float a1) {
+  return(a1);
 }
 
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp	(revision 90569)
+++ lib/Sema/SemaDeclAttr.cpp	(working copy)
@@ -202,91 +202,6 @@
   }
 }
 
-
-/// HandleVectorSizeAttribute - this attribute is only applicable to integral
-/// and float scalars, although arrays, pointers, and function return values are
-/// allowed in conjunction with this construct. Aggregates with this attribute
-/// are invalid, even if they are of the same size as a corresponding scalar.
-/// The raw attribute should contain precisely 1 argument, the vector size for
-/// the variable, measured in bytes. If curType and rawAttr are well formed,
-/// this routine will return a new vector type.
-static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
-  QualType CurType;
-  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
-    CurType = VD->getType();
-  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
-    CurType = TD->getUnderlyingType();
-  else {
-    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
-      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
-    return;
-  }
-
-  // Check the attribute arugments.
-  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)
-      << "vector_size" << sizeExpr->getSourceRange();
-    return;
-  }
-  // navigate to the base type - we need to provide for vector pointers, vector
-  // arrays, and functions returning vectors.
-  if (CurType->isPointerType() || CurType->isArrayType() ||
-      CurType->isFunctionType()) {
-    S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
-    return;
-    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
-     do {
-     if (PointerType *PT = dyn_cast<PointerType>(canonType))
-     canonType = PT->getPointeeType().getTypePtr();
-     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
-     canonType = AT->getElementType().getTypePtr();
-     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
-     canonType = FT->getResultType().getTypePtr();
-     } while (canonType->isPointerType() || canonType->isArrayType() ||
-     canonType->isFunctionType());
-     */
-  }
-  // the base type must be integer or float, and can't already be a vector.
-  if (CurType->isVectorType() ||
-      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
-    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();
-    return;
-  }
-  if (vectorSize == 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
-      << sizeExpr->getSourceRange();
-    return;
-  }
-
-  // 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);
-
-  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
-    VD->setType(CurType);
-  else {
-    // FIXME: preserve existing source info.
-    DeclaratorInfo *DInfo = S.Context.getTrivialDeclaratorInfo(CurType);
-    cast<TypedefDecl>(D)->setTypeDeclaratorInfo(DInfo);
-  }
-}
-
 static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
   if (Attr.getNumArgs() > 0) {
@@ -1964,6 +1879,7 @@
   case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
   case AttributeList::AT_address_space:
   case AttributeList::AT_objc_gc:
+  case AttributeList::AT_vector_size:
     // Ignore these, these are type attributes, handled by
     // ProcessTypeAttributes.
     break;
@@ -2013,7 +1929,6 @@
   case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
   case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
   case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
-  case AttributeList::AT_vector_size: HandleVectorSizeAttr  (D, Attr, S); break;
   case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
   case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
     break;
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 90569)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -1643,6 +1643,53 @@
   Type = S.Context.getNoReturnType(Type);
 }
 
+/// HandleVectorSizeAttribute - this attribute is only applicable to integral
+/// and float scalars, although arrays, pointers, and function return values are
+/// allowed in conjunction with this construct. Aggregates with this attribute
+/// are invalid, even if they are of the same size as a corresponding scalar.
+/// The raw attribute should contain precisely 1 argument, the vector size for
+/// the variable, measured in bytes. If curType and rawAttr are well formed,
+/// this routine will return a new vector type.
+static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) {
+  // Check the attribute arugments.
+  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)
+      << "vector_size" << sizeExpr->getSourceRange();
+    return;
+  }
+  // the base type must be integer or float, and can't already be a vector.
+  if (CurType->isVectorType() ||
+      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+    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();
+    return;
+  }
+  if (vectorSize == 0) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
+      << sizeExpr->getSourceRange();
+    return;
+  }
+
+  // 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);
+}
+
 void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
   // Scan through and apply attributes to this type where it makes sense.  Some
   // attributes (such as __address_space__, __vector_size__, etc) apply to the
@@ -1662,6 +1709,9 @@
     case AttributeList::AT_noreturn:
       HandleNoReturnTypeAttribute(Result, *AL, *this);
       break;
+    case AttributeList::AT_vector_size:
+      HandleVectorSizeAttr(Result, *AL, *this);
+      break;
     }
   }
 }
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp	(revision 90569)
+++ lib/AST/TypePrinter.cpp	(working copy)
@@ -242,12 +242,13 @@
 void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
   // FIXME: We prefer to print the size directly here, but have no way
   // to get the size of the type.
-  S += " __attribute__((__vector_size__(";
-  S += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+  Print(T->getElementType(), S);
+  std::string V = "__attribute__((__vector_size__(";
+  V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
   std::string ET;
   Print(T->getElementType(), ET);
-  S += " * sizeof(" + ET + "))))";
-  Print(T->getElementType(), S);
+  V += " * sizeof(" + ET + ")))) ";
+  S = V + S;
 }
 
 void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 
