diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 39bd5ac..512a7eb 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -200,6 +200,9 @@ def warn_decl_shadow :
           "static data member of %2|"
           "field of %2}1">,
   InGroup<Shadow>, DefaultIgnore;
+def warn_function_shadows_tag_type : Warning<
+  "function %0 shadows %1 %0; uses of %1 %0 will require an '%1' tag">,
+  InGroup<Shadow>;
 
 // C++ using declarations
 def err_using_requires_qualname : Error<
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 31c410a..9632487 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1118,7 +1118,7 @@ public:
   // Returns true if the variable declaration is a redeclaration
   bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
   void CheckCompleteVariableDeclaration(VarDecl *var);
-  void ActOnStartFunctionDeclarator();
+  void ActOnStartFunctionDeclarator(Scope* S, Declarator& D);
   void ActOnEndFunctionDeclarator();
   NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      TypeSourceInfo *TInfo,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 0851941..ca2d312 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -4136,7 +4136,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
   ParsedAttributes FnAttrs(AttrFactory);
   ParsedType TrailingReturnType;
 
-  Actions.ActOnStartFunctionDeclarator();
+  Actions.ActOnStartFunctionDeclarator(getCurScope(), D);
 
   SourceLocation EndLoc;
   if (isFunctionDeclaratorIdentifierList()) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f54f0fd..be5578b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1264,7 +1264,20 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
   }
 }
 
-void Sema::ActOnStartFunctionDeclarator() {
+void Sema::ActOnStartFunctionDeclarator(Scope* S, Declarator& D) {
+  IdentifierInfo *Name = D.getIdentifier();
+  LookupResult R(*this, DeclarationNameInfo(Name, D.getIdentifierLoc()),
+                 Sema::LookupTagName);
+  if (LookupName(R, S)) {
+    for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) {
+      if (TagDecl *TD = dyn_cast_or_null<TagDecl>(*I)) {
+        Diag(D.getIdentifierLoc(), diag::warn_function_shadows_tag_type)
+            << Name << TD->getKindName();
+        Diag(TD->getLocStart(), diag::note_previous_decl) << Name;
+      }
+    }
+  }
+
   ++InFunctionDeclarator;
 }
 
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 68e9467..176215b 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -81,3 +81,12 @@ void rdar8883302() {
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
 }
+
+namespace TagShadow {
+class Foo {
+ public:
+  enum Bar { X, Y }; // expected-note {{'Bar' declared here}}
+  void SetBar(Bar bar);
+  Bar Bar(); // expected-warning {{function 'Bar' shadows enum 'Bar'; uses of enum 'Bar' will require an 'enum' tag}}
+};
+}
