http://reviews.llvm.org/D6295

 

Files:

  include/clang/AST/Mangle.h

  lib/AST/ItaniumMangle.cpp

  lib/CodeGen/CodeGenFunction.cpp

  test/CodeGenCXX/mangle-local-anonymous-unions.cpp

  test/CodeGenCXX/mangle.cpp
Index: include/clang/AST/Mangle.h
===================================================================
--- include/clang/AST/Mangle.h
+++ include/clang/AST/Mangle.h
@@ -71,7 +71,8 @@
   DiagnosticsEngine &getDiags() const { return Diags; }
 
   virtual void startNewFunction() { LocalBlockIds.clear(); }
-  
+  virtual void processNewFunction(const FunctionDecl &FD) {}
+
   unsigned getBlockId(const BlockDecl *BD, bool Local) {
     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
       = Local? LocalBlockIds : GlobalBlockIds;
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -115,9 +115,11 @@
 
 class ItaniumMangleContextImpl : public ItaniumMangleContext {
   typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
-  llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
+  llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminators;
   llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
-  
+private:
+  unsigned uniquifyNamedDecl(const NamedDecl *ND);
+
 public:
   explicit ItaniumMangleContextImpl(ASTContext &Context,
                                     DiagnosticsEngine &Diags)
@@ -162,37 +164,8 @@
 
   void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
 
-  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
-    // Lambda closure types are already numbered.
-    if (isLambda(ND))
-      return false;
-
-    // Anonymous tags are already numbered.
-    if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
-      if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
-        return false;
-    }
-
-    // Use the canonical number for externally visible decls.
-    if (ND->isExternallyVisible()) {
-      unsigned discriminator = getASTContext().getManglingNumber(ND);
-      if (discriminator == 1)
-        return false;
-      disc = discriminator - 2;
-      return true;
-    }
-
-    // Make up a reasonable number for internal decls.
-    unsigned &discriminator = Uniquifier[ND];
-    if (!discriminator) {
-      const DeclContext *DC = getEffectiveDeclContext(ND);
-      discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
-    }
-    if (discriminator == 1)
-      return false;
-    disc = discriminator-2;
-    return true;
-  }
+  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc);
+  void processNewFunction(const FunctionDecl &FD) override;
   /// @}
 };
 
@@ -3733,7 +3706,7 @@
                                  "Mangling declaration");
 
   CXXNameMangler Mangler(*this, Out, D);
-  return Mangler.mangle(D);
+  Mangler.mangle(D);
 }
 
 void ItaniumMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
@@ -3922,3 +3895,62 @@
 ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
   return new ItaniumMangleContextImpl(Context, Diags);
 }
+
+static bool isDiscriminatorNeeded(const NamedDecl *ND) {
+  // Lambda closure types are already numbered.
+  if (isLambda(ND))
+    return false;
+
+  // Anonymous tags are already numbered.
+  if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
+    if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
+      return false;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+      return VD->isStaticLocal() || VD->isExternallyVisible();
+  }
+
+  return true;
+}
+
+unsigned ItaniumMangleContextImpl::uniquifyNamedDecl(const NamedDecl *ND) {
+ if (IdentifierInfo *Identifier = ND->getIdentifier()) {
+    const NamedDecl *D = ND;
+    if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(ND)) {
+      D = IFD->getVarDecl();
+    }
+    unsigned &Discriminator = Uniquifier[D];
+    if (!Discriminator) {
+      const DeclContext *DC = getEffectiveDeclContext(D);
+      Discriminator = ++Discriminators[std::make_pair(DC, Identifier)];
+    }
+    return Discriminator;
+  } else
+    return 0;
+}
+
+void ItaniumMangleContextImpl::processNewFunction(const FunctionDecl &FD) {
+  for (auto D: FD.decls()) {
+    if (const NamedDecl * ND = dyn_cast<NamedDecl>(D)) {
+      if (isDiscriminatorNeeded(ND))
+        uniquifyNamedDecl(ND);
+    }
+  }
+}
+
+bool ItaniumMangleContextImpl::getNextDiscriminator(const NamedDecl *ND,
+                                                unsigned &disc) {
+  if (!isDiscriminatorNeeded(ND))
+    return false;
+
+  unsigned Discriminator = Uniquifier[ND];
+  if (!Discriminator) {
+    Discriminator = uniquifyNamedDecl(ND);
+  }
+  if (Discriminator <= 1)
+    return false;
+  disc = Discriminator-2;
+  return true;
+}
+
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -809,6 +809,7 @@
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                                    const CGFunctionInfo &FnInfo) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+  CGM.getCXXABI().getMangleContext().processNewFunction(*FD);
 
   // Check if we should generate debug info for this function.
   if (FD->hasAttr<NoDebugAttr>())
Index: test/CodeGenCXX/mangle-local-anonymous-unions.cpp
===================================================================
--- test/CodeGenCXX/mangle-local-anonymous-unions.cpp
+++ test/CodeGenCXX/mangle-local-anonymous-unions.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+// CHECK-DAG: @_ZZ2f0vE1a
+// CHECK-DAG: @_ZZ2f0vE1c
+// CHECK-DAG: @_ZZ2f0vE1e_0
+inline int f0() {
+  static union {
+    int a;
+    long int b;
+  };
+
+  static union {
+    int c;
+    double d;
+  };
+
+  if (0) {
+    static union {
+      int e;
+      int f;
+    };
+  }
+  static union {
+    int e;
+    int f;
+  };
+
+  return a+c;
+}
+
+// CHECK-DAG: @_ZZ2f1vE1a
+// CHECK-DAG: @_ZZ2f1vE1c
+// CHECK-DAG: @_ZZ2f1vE1c_0
+// CHECK-DAG: @_ZZ2f1vE1c_1
+// CHECK-DAG: @_ZZ2f1vE1e_0
+int f1 () {
+  static union {
+    int a;
+    long int b;
+  };
+
+  static union {
+    int c;
+    double d;
+  };
+
+  { static int c; }
+  { static int c; }
+
+  if (0) {
+    static union {
+      int e;
+      int f;
+    };
+  }
+  static union {
+    int e;
+    int f;
+  };
+
+  return a+c+f0();
+}
+
Index: test/CodeGenCXX/mangle.cpp
===================================================================
--- test/CodeGenCXX/mangle.cpp
+++ test/CodeGenCXX/mangle.cpp
@@ -899,7 +899,7 @@
 }
 
 namespace test40 {
-  // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
+  // CHECK-DAG: i32* {{.*}} @_ZZN6test401fEvE1a_0
   void h(int&);
   inline void f() {
     if (0) {
@@ -908,7 +908,15 @@
     static int a;
     h(a);
   };
-  void g() { f(); }
+  // CHECK-DAG: i32* {{.*}} @_ZZN6test402ffEvE1a_0
+  void ff() {
+    if (0) {
+      static int a;
+    }
+    static int a;
+    h(a);
+  }
+  void g() { f(); ff(); }
 }
 
 namespace test41 {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to