]> granicus.if.org Git - clang/commitdiff
When mangling for the Microsoft C++ ABI, mangle variables in the global
authorCharles Davis <cdavis@mines.edu>
Fri, 11 Jun 2010 04:25:47 +0000 (04:25 +0000)
committerCharles Davis <cdavis@mines.edu>
Fri, 11 Jun 2010 04:25:47 +0000 (04:25 +0000)
namespace, too.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105809 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.h
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/mangle-ms.cpp

index a12a140f725259978bb66fd85fdfbed538b3dd50..d10334dcbb34313d88cc169c806685991e565df3 100644 (file)
@@ -110,7 +110,7 @@ public:
   /// @name Mangler Entry Points
   /// @{
 
-  bool shouldMangleDeclName(const NamedDecl *D);
+  virtual bool shouldMangleDeclName(const NamedDecl *D);
   virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
   virtual void mangleThunk(const CXXMethodDecl *MD,
                           const ThunkInfo &Thunk,
index 948a66f665a06de874e55c7dccb38285fa2260bb..012ef23c1c4f8ffb07dcddd9ae37f38f8163691c 100644 (file)
@@ -64,6 +64,7 @@ class MicrosoftMangleContext : public MangleContext {
 public:
   MicrosoftMangleContext(ASTContext &Context,
                          Diagnostic &Diags) : MangleContext(Context, Diags) { }
+  virtual bool shouldMangleDeclName(const NamedDecl *D);
   virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
   virtual void mangleThunk(const CXXMethodDecl *MD,
                            const ThunkInfo &Thunk,
@@ -101,6 +102,46 @@ public:
 
 }
 
+static bool isInCLinkageSpecification(const Decl *D) {
+  D = D->getCanonicalDecl();
+  for (const DeclContext *DC = D->getDeclContext();
+       !DC->isTranslationUnit(); DC = DC->getParent()) {
+    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
+      return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
+  }
+  
+  return false;
+}
+
+bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
+  // In C, functions with no attributes never need to be mangled. Fastpath them.
+  if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
+    return false;
+
+  // Any decl can be declared with __asm("foo") on it, and this takes precedence
+  // over all other naming in the .o file.
+  if (D->hasAttr<AsmLabelAttr>())
+    return true;
+
+  // Clang's "overloadable" attribute extension to C/C++ implies name mangling
+  // (always) as does passing a C++ member function and a function
+  // whose name is not a simple identifier.
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
+             !FD->getDeclName().isIdentifier()))
+    return true;
+
+  // Otherwise, no mangling is done outside C++ mode.
+  if (!getASTContext().getLangOptions().CPlusPlus)
+    return false;
+
+  // C functions and "main" are not mangled.
+  if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
+    return false;
+
+  return true;
+}
+
 void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
                                      llvm::StringRef Prefix) {
   // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
index 27ae8bf919cae923145742695c1d65ad4881c6bd..68640ca2924f5390ac7e39e285a3426a5fea96ee 100644 (file)
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
 
-//int a; // FIXME: All names not in an extern "C" block are mangled
+int a;
+// CHECK: @"\01?a@@"
 
 namespace N { int b; }
 // CHECK: @"\01?b@N@@"