Tweak to r147599 for PR10828: Move the check from the parser into sema, and use
the Semantic Powers to only warn on class types (or dependent types), where the
constructor or destructor could do something interesting.

llvm-svn: 147642
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index d3c8211..ee4a51e 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1111,21 +1111,6 @@
   if (FirstDecl)
     DeclsInGroup.push_back(FirstDecl);
 
-  // In C++, "T var();" at block scope is probably an attempt to initialize a
-  // variable, not a function declaration. We don't catch this case earlier,
-  // since there is no ambiguity here.
-  if (getLang().CPlusPlus && Context != Declarator::FileContext &&
-      D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() &&
-      D.getDeclSpec().getStorageClassSpecAsWritten()
-        == DeclSpec::SCS_unspecified &&
-      D.getDeclSpec().getTypeSpecType() != DeclSpec::TST_void) {
-    DeclaratorChunk &C = D.getTypeObject(0);
-    if (C.Fun.NumArgs == 0 && !C.Fun.isVariadic && !C.Fun.TrailingReturnType &&
-        C.Fun.getExceptionSpecType() == EST_None)
-      Diag(C.Loc, diag::warn_empty_parens_are_function_decl)
-        << SourceRange(C.Loc, C.EndLoc);
-  }
-
   bool ExpectSemi = Context != Declarator::ForContext;
 
   // If we don't have a comma, it is either the end of the list (a ';') or an
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8353c08..3e9e66d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4904,6 +4904,25 @@
         FunctionTemplate->setInvalidDecl();
     }
 
+    // If we see "T var();" at block scope, where T is a class type, it is
+    // probably an attempt to initialize a variable, not a function declaration.
+    // We don't catch this case earlier, since there is no ambiguity here.
+    if (!FunctionTemplate && D.getFunctionDefinitionKind() == FDK_Declaration &&
+        CurContext->isFunctionOrMethod() &&
+        D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() &&
+        D.getDeclSpec().getStorageClassSpecAsWritten()
+          == DeclSpec::SCS_unspecified) {
+      QualType T = R->getAs<FunctionType>()->getResultType();
+      DeclaratorChunk &C = D.getTypeObject(0);
+      if ((T->isDependentType() || T->isRecordType()) &&
+          C.Fun.NumArgs == 0 && !C.Fun.isVariadic &&
+          !C.Fun.TrailingReturnType &&
+          C.Fun.getExceptionSpecType() == EST_None) {
+        Diag(C.Loc, diag::warn_empty_parens_are_function_decl)
+          << SourceRange(C.Loc, C.EndLoc);
+      }
+    }
+
     // C++ [dcl.fct.spec]p5:
     //   The virtual specifier shall only be used in declarations of
     //   nonstatic class member functions that appear within a