[cfe-commits] r97658 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/mangle-local-class-names.cpp

Fariborz Jahanian fjahanian at apple.com
Wed Mar 3 11:41:08 PST 2010


Author: fjahanian
Date: Wed Mar  3 13:41:08 2010
New Revision: 97658

URL: http://llvm.org/viewvc/llvm-project?rev=97658&view=rev
Log:
Implements mangling of local class names to
fix a code gen crash. This is WIP as not
all ABI cases are covered (there is a FIXME to 
this effect). Fixes radar 7696748.

Added:
    cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp
Modified:
    cfe/trunk/lib/CodeGen/Mangle.cpp

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=97658&r1=97657&r2=97658&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Mar  3 13:41:08 2010
@@ -37,7 +37,19 @@
 using namespace CodeGen;
 
 namespace {
-  
+
+static const DeclContext *GetLocalClassFunctionDeclContext(
+                                                      const DeclContext *DC) {
+  if (isa<CXXRecordDecl>(DC)) {
+    while (!DC->isNamespace() && !DC->isTranslationUnit() &&
+           !isa<FunctionDecl>(DC))
+      DC = DC->getParent();
+    if (isa<FunctionDecl>(DC))
+      return DC;
+  }
+  return 0;
+}
+
 static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
   assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
          "Passed in decl is not a ctor or dtor!");
@@ -53,6 +65,8 @@
 }
 
 static const unsigned UnknownArity = ~0U;
+static unsigned Discriminator = 0;
+static llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
   
 /// CXXNameMangler - Manage the mangling of a single name.
 class CXXNameMangler {
@@ -61,7 +75,7 @@
 
   const CXXMethodDecl *Structor;
   unsigned StructorType;
-
+  
   llvm::DenseMap<uintptr_t, unsigned> Substitutions;
 
   ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -128,11 +142,12 @@
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
   void mangleSourceName(const IdentifierInfo *II);
   void mangleLocalName(const NamedDecl *ND);
-  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC);
+  void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
+                        bool NoFunction=false);
   void mangleNestedName(const TemplateDecl *TD,
                         const TemplateArgument *TemplateArgs,
                         unsigned NumTemplateArgs);
-  void manglePrefix(const DeclContext *DC);
+  void manglePrefix(const DeclContext *DC, bool NoFunction=false);
   void mangleTemplatePrefix(const TemplateDecl *ND);
   void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
   void mangleQualifiers(Qualifiers Quals);
@@ -342,7 +357,12 @@
   //         ::= <local-name>
   //
   const DeclContext *DC = ND->getDeclContext();
-
+  
+  if (GetLocalClassFunctionDeclContext(DC)) {
+    mangleLocalName(ND);
+    return;
+  }
+  
   // If this is an extern variable declared locally, the relevant DeclContext
   // is that of the containing namespace, or the translation unit.
   if (isa<FunctionDecl>(DC) && ND->hasLinkage())
@@ -603,7 +623,8 @@
 }
 
 void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
-                                      const DeclContext *DC) {
+                                      const DeclContext *DC,
+                                      bool NoFunction) {
   // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
   //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
 
@@ -616,8 +637,9 @@
   if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
     mangleTemplatePrefix(TD);
     mangleTemplateArgs(*TemplateArgs);
-  } else {
-    manglePrefix(DC);
+  }
+  else {
+    manglePrefix(DC, NoFunction);
     mangleUnqualifiedName(ND);
   }
 
@@ -640,18 +662,38 @@
   // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
   //              := Z <function encoding> E s [<discriminator>]
   // <discriminator> := _ <non-negative number>
+  const DeclContext *DC = ND->getDeclContext();
   Out << 'Z';
   
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND->getDeclContext()))
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
     mangleObjCMethodName(MD);
+  else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
+    mangleFunctionEncoding(cast<FunctionDecl>(CDC));
+    Out << 'E';
+    mangleNestedName(ND, DC, true /*NoFunction*/);
+    
+    // FIXME. This still does not conform to ABI and does not cover all cases.
+    unsigned &discriminator = Uniquifier[ND];
+    if (!discriminator)
+      discriminator = ++Discriminator;
+    if (discriminator == 1)
+      return;
+    unsigned disc = discriminator-2;
+    if (disc < 10)
+      Out << '_' << disc;
+    else 
+      Out << "__" << disc << '_';
+
+    return;
+  }
   else  
-    mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
+    mangleFunctionEncoding(cast<FunctionDecl>(DC));
 
   Out << 'E';
   mangleUnqualifiedName(ND);
 }
 
-void CXXNameMangler::manglePrefix(const DeclContext *DC) {
+void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
   //  <prefix> ::= <prefix> <unqualified-name>
   //           ::= <template-prefix> <template-args>
   //           ::= <template-param>
@@ -672,8 +714,11 @@
   if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
     mangleTemplatePrefix(TD);
     mangleTemplateArgs(*TemplateArgs);
-  } else {
-    manglePrefix(DC->getParent());
+  }
+  else if(NoFunction && isa<FunctionDecl>(DC))
+    return;
+  else {
+    manglePrefix(DC->getParent(), NoFunction);
     mangleUnqualifiedName(cast<NamedDecl>(DC));
   }
 

Added: cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp?rev=97658&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp Wed Mar  3 13:41:08 2010
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK:  @_ZZ4FUNCvEN4SSSSC1ERKf
+// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
+
+void FUNC ()
+{
+  {
+    float IVAR1 ;
+
+    struct SSSS 
+    {
+      float bv;
+      SSSS( const float& from): bv(from) { }
+    };
+
+    SSSS VAR1(IVAR1);
+   }
+
+   {
+    float IVAR2 ;
+
+    struct SSSS
+    {
+     SSSS( const float& from) {}
+    };
+
+    SSSS VAR2(IVAR2);
+   }
+}





More information about the cfe-commits mailing list