[-cxx-abi microsoft] Correctly identify Win32 entry points

Summary:
This fixes several issues with the original implementation:
- Win32 entry points cannot be in namespaces
- A Win32 entry point cannot be a function template, diagnose if we it.
- Win32 entry points cannot be overloaded.
- Win32 entry points implicitly return, similar to main.

Reviewers: rnk, rsmith, whunt, timurrrr

Reviewed By: rnk

CC: cfe-commits, nrieck

Differential Revision: http://llvm-reviews.chandlerc.com/D1683

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190818 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1c2ead0..0fa1b98 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2204,6 +2204,33 @@
          isNamed(this, "main");
 }
 
+bool FunctionDecl::isMSVCRTEntryPoint() const {
+  const TranslationUnitDecl *TUnit =
+      dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
+  if (!TUnit)
+    return false;
+
+  // Even though we aren't really targeting MSVCRT if we are freestanding,
+  // semantic analysis for these functions remains the same.
+
+  // MSVCRT entry points only exist on MSVCRT targets.
+  if (!TUnit->getASTContext().getTargetInfo().getTriple().isOSMSVCRT())
+    return false;
+
+  // Nameless functions like constructors cannot be entry points.
+  if (!getIdentifier())
+    return false;
+
+  return llvm::StringSwitch<bool>(getName())
+      .Cases("main",     // an ANSI console app
+             "wmain",    // a Unicode console App
+             "WinMain",  // an ANSI GUI app
+             "wWinMain", // a Unicode GUI app
+             "DllMain",  // a DLL
+             true)
+      .Default(false);
+}
+
 bool FunctionDecl::isReservedGlobalPlacementOperator() const {
   assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName);
   assert(getDeclName().getCXXOverloadedOperator() == OO_New ||
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 9cea061..8506c4c 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -24,7 +24,6 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSwitch.h"
 
 using namespace clang;
 
@@ -71,29 +70,6 @@
   return fn;
 }
 
-// The ABI expects that we would never mangle "typical" user-defined entry
-// points regardless of visibility or freestanding-ness.
-//
-// N.B. This is distinct from asking about "main".  "main" has a lot of special
-// rules associated with it in the standard while these user-defined entry
-// points are outside of the purview of the standard.  For example, there can be
-// only one definition for "main" in a standards compliant program; however
-// nothing forbids the existence of wmain and WinMain in the same translation
-// unit.
-static bool isUserDefinedEntryPoint(const FunctionDecl *FD) {
-  if (!FD->getIdentifier())
-    return false;
-
-  return llvm::StringSwitch<bool>(FD->getName())
-      .Cases("main",     // An ANSI console app
-             "wmain",    // A Unicode console App
-             "WinMain",  // An ANSI GUI app
-             "wWinMain", // A Unicode GUI app
-             "DllMain",  // A DLL
-             true)
-      .Default(false);
-}
-
 /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftCXXNameMangler {
@@ -254,7 +230,16 @@
     if (FD->hasAttr<OverloadableAttr>())
       return true;
 
-    if (isUserDefinedEntryPoint(FD))
+    // The ABI expects that we would never mangle "typical" user-defined entry
+    // points regardless of visibility or freestanding-ness.
+    //
+    // N.B. This is distinct from asking about "main".  "main" has a lot of
+    // special rules associated with it in the standard while these
+    // user-defined entry points are outside of the purview of the standard.
+    // For example, there can be only one definition for "main" in a standards
+    // compliant program; however nothing forbids the existence of wmain and
+    // WinMain in the same translation unit.
+    if (FD->isMSVCRTEntryPoint())
       return false;
 
     // C++ functions and those whose names are not a simple identifier need