diff --git include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/DiagnosticSemaKinds.td
index e85f835..a942745 100644
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -818,6 +818,8 @@ def err_qualified_friend_def : Error<
   "friend function definition cannot be qualified with '%0'">;
 def err_friend_def_in_local_class : Error<
   "friend function cannot be defined in a local class">;
+def err_friend_not_first_in_declaration : Error<
+  "'friend' must appear first in a non-function declaration">;
   
 def err_abstract_type_in_decl : Error<
   "%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">;
diff --git lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclCXX.cpp
index 5ee28da..229a687 100644
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -9879,7 +9879,7 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation Loc,
              diag::warn_cxx98_compat_nonclass_type_friend :
              diag::ext_nonclass_type_friend)
         << T
-        << SourceRange(FriendLoc, TypeRange.getEnd());
+        << TypeRange;
     }
   } else if (T->getAs<EnumType>()) {
     Diag(FriendLoc,
@@ -9887,7 +9887,7 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation Loc,
            diag::warn_cxx98_compat_enum_friend :
            diag::ext_enum_friend)
       << T
-      << SourceRange(FriendLoc, TypeRange.getEnd());
+      << TypeRange;
   }
   
   // C++0x [class.friend]p3:
@@ -9895,8 +9895,15 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation Loc,
   //   cv-qualified) class type, that class is declared as a friend; otherwise, 
   //   the friend declaration is ignored.
   
-  // FIXME: C++0x has some syntactic restrictions on friend type declarations
-  // in [class.friend]p3 that we do not implement.
+  // A friend declaration that does not declare a function shall have one
+  // of the following forms:
+  //   friend elaborated-type-specifier ;
+  //   friend simple-type-specifier ;
+  //   friend typename-specifier ;
+  if (getLangOpts().CPlusPlus0x && Loc != FriendLoc) {
+    Diag(FriendLoc, diag::err_friend_not_first_in_declaration) << T;
+    return 0;
+  }
   
   return FriendDecl::Create(Context, CurContext, Loc, TSInfo, FriendLoc);
 }
diff --git test/CXX/class/class.friend/p3.cpp test/CXX/class/class.friend/p3.cpp
new file mode 100644
index 0000000..d6f47c7
--- /dev/null
+++ test/CXX/class/class.friend/p3.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename T>
+class A {
+  T x;
+public:
+  class foo {};
+  static int y;
+};
+
+struct {
+  // Ill-formed
+  int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
+  unsigned friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
+  const volatile friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
+  int
+          friend; // expected-error {{'friend' must appear first in a non-function declaration}}
+
+  // OK
+  int friend foo(void);
+  friend int;
+  friend const volatile int;
+      friend
+
+  float;
+  template<typename T> friend class A<T>::foo;
+} a;
