From 978c5e0c239189117481b00fbba30101195f7e2c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 13 Sep 2013 09:40:55 +0000 Subject: [PATCH] [-cxx-abi microsoft] Mangle user defined entry points properly Summary: Functions named "main", "wmain", "WinMain", "wWinMain", and "DllMain" are never mangled regardless of linkage, even when compiling for kernel mode. Depends on D1655 Reviewers: timurrrr, pcc, rnk, whunt CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1670 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190675 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/MicrosoftMangle.cpp | 27 +++++++++++++++++++++++++-- test/CodeGenCXX/mangle-ms.cpp | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index e082759cb9..9cea06187e 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -24,6 +24,7 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -70,6 +71,29 @@ static const FunctionDecl *getStructor(const FunctionDecl *fn) { 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(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 { @@ -230,8 +254,7 @@ bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) { if (FD->hasAttr()) return true; - // "main" is not mangled. - if (FD->isMain()) + if (isUserDefinedEntryPoint(FD)) return false; // C++ functions and those whose names are not a simple identifier need diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index e7450d8fb0..8b7aa4223d 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -255,3 +255,23 @@ extern "C" inline void extern_c_func() { void call_extern_c_func() { extern_c_func(); } + +int main() { return 0; } +// CHECK-DAG: @main +// X64-DAG: @main + +int wmain() { return 0; } +// CHECK-DAG: @wmain +// X64-DAG: @wmain + +int WinMain() { return 0; } +// CHECK-DAG: @WinMain +// X64-DAG: @WinMain + +int wWinMain() { return 0; } +// CHECK-DAG: @wWinMain +// X64-DAG: @wWinMain + +int DllMain() { return 0; } +// CHECK-DAG: @DllMain +// X64-DAG: @DllMain -- 2.40.0