diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-09-16 22:44:20 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-09-16 22:44:20 +0000 |
commit | c729b0b50669e976f289ac92e0d697aafd6f7b64 (patch) | |
tree | d9585179b605bf86c6f55444af48b76ccdc0153e /clang/lib/AST | |
parent | 899f7d2b00a59f284fdb8915b63813705ce66148 (diff) | |
download | bcm5719-llvm-c729b0b50669e976f289ac92e0d697aafd6f7b64.tar.gz bcm5719-llvm-c729b0b50669e976f289ac92e0d697aafd6f7b64.zip |
[-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
llvm-svn: 190818
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 27 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 35 |
2 files changed, 37 insertions, 25 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1c2ead0ee59..0fa1b980f31 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2204,6 +2204,33 @@ bool FunctionDecl::isMain() const { 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/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 9cea06187e2..8506c4c8dde 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/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 @@ 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<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 @@ bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) { 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 |