alexbdv updated this revision to Diff 257508.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74813/new/

https://reviews.llvm.org/D74813

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/Mangle.cpp
  clang/lib/CodeGen/CGBlocks.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h

Index: clang/lib/CodeGen/CodeGenModule.h
===================================================================
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -1173,7 +1173,8 @@
   void AddDefaultFnAttrs(llvm::Function &F);
 
   StringRef getMangledName(GlobalDecl GD);
-  StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
+  StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD,
+                                const StringRef *parentFuncName);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1177,7 +1177,8 @@
 }
 
 StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
-                                             const BlockDecl *BD) {
+                                             const BlockDecl *BD,
+                                             const StringRef *parentFuncName) {
   MangleContext &MangleCtx = getCXXABI().getMangleContext();
   const Decl *D = GD.getDecl();
 
@@ -1187,11 +1188,11 @@
     MangleCtx.mangleGlobalBlock(BD,
       dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
   else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D))
-    MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
+    MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out, parentFuncName);
   else if (const auto *DD = dyn_cast<CXXDestructorDecl>(D))
-    MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Out);
+    MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Out, parentFuncName);
   else
-    MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out);
+    MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out, parentFuncName);
 
   auto Result = Manglings.insert(std::make_pair(Out.str(), BD));
   return Result.first->first();
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -212,7 +212,8 @@
   if (const auto *FD = dyn_cast<FunctionDecl>(DC))
     ContextName = std::string(CGM.getMangledName(FD));
   else if (const auto *BD = dyn_cast<BlockDecl>(DC))
-    ContextName = std::string(CGM.getBlockMangledName(GlobalDecl(), BD));
+    ContextName =
+        std::string(CGM.getBlockMangledName(GlobalDecl(), BD, nullptr));
   else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
     ContextName = OMD->getSelector().getAsString();
   else
Index: clang/lib/CodeGen/CGBlocks.cpp
===================================================================
--- clang/lib/CodeGen/CGBlocks.cpp
+++ clang/lib/CodeGen/CGBlocks.cpp
@@ -1571,7 +1571,7 @@
 
   llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
 
-  StringRef name = CGM.getBlockMangledName(GD, blockDecl);
+  StringRef name = CGM.getBlockMangledName(GD, blockDecl, &blockInfo.Name);
   llvm::Function *fn = llvm::Function::Create(
       fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());
   CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
Index: clang/lib/AST/Mangle.cpp
===================================================================
--- clang/lib/AST/Mangle.cpp
+++ clang/lib/AST/Mangle.cpp
@@ -26,21 +26,70 @@
 #include "llvm/IR/Mangler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include <sstream>
+#include <iostream>
+#include <iomanip>
 
 using namespace clang;
 
+static std::string getBlockDeclHash(const BlockDecl *BD, 
+                                    const StringRef *parentFuncName) {
+  std::vector<unsigned> hashItems;
+
+  ArrayRef<ParmVarDecl *> params = BD->parameters();
+  std::string strTypeBuff;
+  llvm::raw_string_ostream osTypeStream(strTypeBuff);
+
+  hashItems.push_back(params.size());
+  for(unsigned i = 0; i < params.size(); i++) {
+    ParmVarDecl *param = params[i];
+
+    osTypeStream << param->getNameAsString();
+    osTypeStream << " [";
+    param->getType()->dump(osTypeStream);
+    osTypeStream << "] \n";
+  }
+
+  osTypeStream.flush();
+
+  // Remove (non-deterministic) pointers from the param string
+  char *ptr = &strTypeBuff[1];
+  while (*ptr) {
+    if (*ptr == 'x' && *(ptr - 1) == '0') {
+      ptr++;
+      while ((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'a' && *ptr <= 'f')) {
+        *ptr = '_';
+        ptr++;
+      }
+      continue;
+    }
+    ptr++;
+  }
+
+  // Hash the param string
+  llvm::MD5 Hash;
+  llvm::MD5::MD5Result Result;
+
+  if(parentFuncName) {
+    Hash.update(*parentFuncName);
+  }
+  Hash.update(strTypeBuff);
+  Hash.final(Result);
+
+  std::ostringstream osRet;
+  unsigned short hash = (*(unsigned short *)&Result);
+
+  osRet << std::hex << std::setfill('0') << std::setw(4) << std::uppercase << hash;
+  return osRet.str();
+}
+
 // FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
 // much to be desired. Come up with a better mangling scheme.
-
-static void mangleFunctionBlock(MangleContext &Context,
-                                StringRef Outer,
-                                const BlockDecl *BD,
-                                raw_ostream &Out) {
-  unsigned discriminator = Context.getBlockId(BD, true);
-  if (discriminator == 0)
-    Out << "__" << Outer << "_block_invoke";
-  else
-    Out << "__" << Outer << "_block_invoke_" << discriminator+1;
+static void mangleFunctionBlock(MangleContext &Context, StringRef Outer,
+                                const BlockDecl *BD, raw_ostream &Out,
+                                const StringRef *parentFuncName) {
+  Out << "__" << Outer << "_block_invoke_"
+      << getBlockDeclHash(BD, parentFuncName);
 }
 
 void MangleContext::anchor() { }
@@ -228,24 +277,27 @@
 
 void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
                                     CXXCtorType CT, const BlockDecl *BD,
-                                    raw_ostream &ResStream) {
+                                    raw_ostream &ResStream,
+                                    const StringRef *parentFuncName) {
   SmallString<64> Buffer;
   llvm::raw_svector_ostream Out(Buffer);
   mangleName(GlobalDecl(CD, CT), Out);
-  mangleFunctionBlock(*this, Buffer, BD, ResStream);
+  mangleFunctionBlock(*this, Buffer, BD, ResStream, parentFuncName);
 }
 
 void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
                                     CXXDtorType DT, const BlockDecl *BD,
-                                    raw_ostream &ResStream) {
+                                    raw_ostream &ResStream,
+                                    const StringRef *parentFuncName) {
   SmallString<64> Buffer;
   llvm::raw_svector_ostream Out(Buffer);
   mangleName(GlobalDecl(DD, DT), Out);
-  mangleFunctionBlock(*this, Buffer, BD, ResStream);
+  mangleFunctionBlock(*this, Buffer, BD, ResStream, parentFuncName);
 }
 
 void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
-                                raw_ostream &Out) {
+                                raw_ostream &Out,
+                                const StringRef *parentFuncName) {
   assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
 
   SmallString<64> Buffer;
@@ -261,9 +313,9 @@
     assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
            "expected a TranslationUnitDecl or a NamedDecl");
     if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
-      mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out);
+      mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out, parentFuncName);
     else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
-      mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out);
+      mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out, parentFuncName);
     else if (auto ND = dyn_cast<NamedDecl>(DC)) {
       if (!shouldMangleDeclName(ND) && ND->getIdentifier())
         Stream << ND->getIdentifier()->getName();
@@ -277,7 +329,7 @@
       }
     }
   }
-  mangleFunctionBlock(*this, Buffer, BD, Out);
+  mangleFunctionBlock(*this, Buffer, BD, Out, parentFuncName);
 }
 
 void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD,
Index: clang/include/clang/AST/Mangle.h
===================================================================
--- clang/include/clang/AST/Mangle.h
+++ clang/include/clang/AST/Mangle.h
@@ -116,11 +116,14 @@
                          const NamedDecl *ID,
                          raw_ostream &Out);
   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
-                       const BlockDecl *BD, raw_ostream &Out);
+                       const BlockDecl *BD, raw_ostream &Out,
+                       const StringRef *parentFuncName);
   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
-                       const BlockDecl *BD, raw_ostream &Out);
+                       const BlockDecl *BD, raw_ostream &Out,
+                       const StringRef *parentFuncName);
   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
-                   raw_ostream &Out);
+                   raw_ostream &Out,
+                   const StringRef *parentFuncName);
 
   void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to