[cfe-commits] r104610 - in /cfe/trunk/lib/CodeGen: CGBlocks.cpp CGCXX.cpp CodeGenFunction.cpp CodeGenModule.h Mangle.cpp Mangle.h

Douglas Gregor dgregor at apple.com
Tue May 25 10:04:15 PDT 2010


Author: dgregor
Date: Tue May 25 12:04:15 2010
New Revision: 104610

URL: http://llvm.org/viewvc/llvm-project?rev=104610&view=rev
Log:
Improve name mangling for blocks and support mangling of static local
variables within blocks. We loosely follow GCC's mangling, but since
these are always internal symbols the names don't really matter. I
intend to revisit block mangling later, because GCC's mangling is
rather verbose. <rdar://problem/8015719>.

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/CodeGen/Mangle.h

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue May 25 12:04:15 2010
@@ -791,9 +791,10 @@
   CodeGenTypes &Types = CGM.getTypes();
   const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
 
+  MangleBuffer Name;
+  CGM.getMangledName(Name, BD);
   llvm::Function *Fn =
-    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
-                           llvm::Twine("__") + Info.Name + "_block_invoke_",
+    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, Name,
                            &CGM.getModule());
 
   CGM.SetInternalFunctionAttributes(BD, Fn, FI);

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue May 25 12:04:15 2010
@@ -230,6 +230,10 @@
                       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
 }
 
+void CodeGenModule::getMangledName(MangleBuffer &Buffer, const BlockDecl *BD) {
+  getMangleContext().mangleBlock(BD, Buffer.getBuffer());
+}
+
 void CodeGenModule::getMangledCXXCtorName(MangleBuffer &Name,
                                           const CXXConstructorDecl *D,
                                           CXXCtorType Type) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue May 25 12:04:15 2010
@@ -37,6 +37,7 @@
   LLVMPointerWidth = Target.getPointerWidth(0);
   Exceptions = getContext().getLangOptions().Exceptions;
   CatchUndefined = getContext().getLangOptions().CatchUndefined;
+  CGM.getMangleContext().startNewFunction();
 }
 
 ASTContext &CodeGenFunction::getContext() const {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue May 25 12:04:15 2010
@@ -413,6 +413,7 @@
 
   void getMangledName(MangleBuffer &Buffer, GlobalDecl D);
   void getMangledName(MangleBuffer &Buffer, const NamedDecl *ND);
+  void getMangledName(MangleBuffer &Buffer, const BlockDecl *BD);
   void getMangledCXXCtorName(MangleBuffer &Buffer,
                              const CXXConstructorDecl *D,
                              CXXCtorType Type);

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Tue May 25 12:04:15 2010
@@ -102,6 +102,7 @@
   llvm::raw_svector_ostream &getStream() { return Out; }
 
   void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
+  void mangleBlock(const BlockDecl *BD);
   void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
   void mangleNumber(int64_t Number);
   void mangleFunctionEncoding(const FunctionDecl *FD);
@@ -469,6 +470,31 @@
   Out << Number;
 }
 
+void CXXNameMangler::mangleBlock(const BlockDecl *BD) {
+  // Mangle the context of the block.
+  // FIXME: We currently mimic GCC's mangling scheme, which leaves much to be
+  // desired. Come up with a better mangling scheme.
+  const DeclContext *DC = BD->getDeclContext();
+  while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
+    DC = DC->getParent();
+  if (DC->isFunctionOrMethod()) {
+    Out << "__";
+    if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
+      mangleObjCMethodName(Method);
+    else {
+      const NamedDecl *ND = cast<NamedDecl>(DC);
+      if (IdentifierInfo *II = ND->getIdentifier())
+        Out << II->getName();
+      else {
+        mangleUnqualifiedName(ND);
+      }
+    }
+    Out << "_block_invoke_" << Context.getBlockId(BD, true);
+  } else {
+    Out << "__block_global_" << Context.getBlockId(BD, false);
+  }
+}
+
 void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) {
   //  <call-offset>  ::= h <nv-offset> _
   //                 ::= v <v-offset> _
@@ -752,6 +778,14 @@
   if (DC->isTranslationUnit())
     return;
 
+  if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
+    manglePrefix(DC->getParent(), NoFunction);    
+    llvm::SmallString<64> Name;
+    Context.mangleBlock(Block, Name);
+    Out << Name.size() << Name;
+    return;
+  }
+  
   if (mangleSubstitution(cast<NamedDecl>(DC)))
     return;
 
@@ -762,8 +796,10 @@
     TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
     mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
   }
-  else if(NoFunction && isa<FunctionDecl>(DC))
+  else if(NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
     return;
+  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
+    mangleObjCMethodName(Method);
   else {
     manglePrefix(DC->getParent(), NoFunction);
     mangleUnqualifiedName(cast<NamedDecl>(DC));
@@ -2033,6 +2069,12 @@
   Mangler.mangle(D);
 }
 
+void MangleContext::mangleBlock(const BlockDecl *BD,
+                                llvm::SmallVectorImpl<char> &Res) {
+  CXXNameMangler Mangler(*this, Res);
+  Mangler.mangleBlock(BD);
+}
+
 void MangleContext::mangleThunk(const CXXMethodDecl *MD,
                                 const ThunkInfo &Thunk,
                                 llvm::SmallVectorImpl<char> &Res) {

Modified: cfe/trunk/lib/CodeGen/Mangle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.h?rev=104610&r1=104609&r2=104610&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.h (original)
+++ cfe/trunk/lib/CodeGen/Mangle.h Tue May 25 12:04:15 2010
@@ -26,6 +26,7 @@
 
 namespace clang {
   class ASTContext;
+  class BlockDecl;
   class CXXConstructorDecl;
   class CXXDestructorDecl;
   class CXXMethodDecl;
@@ -73,6 +74,8 @@
   llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
   unsigned Discriminator;
   llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
+  llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
+  llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
   
 public:
   explicit MangleContext(ASTContext &Context,
@@ -83,6 +86,8 @@
 
   Diagnostic &getDiags() const { return Diags; }
 
+  void startNewFunction() { LocalBlockIds.clear(); }
+  
   uint64_t getAnonymousStructId(const TagDecl *TD) {
     std::pair<llvm::DenseMap<const TagDecl *,
       uint64_t>::iterator, bool> Result =
@@ -90,11 +95,18 @@
     return Result.first->second;
   }
 
+  unsigned getBlockId(const BlockDecl *BD, bool Local) {
+    llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
+      = Local? LocalBlockIds : GlobalBlockIds;
+    std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
+      Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
+    return Result.first->second;
+  }
+  
   /// @name Mangler Entry Points
   /// @{
 
   bool shouldMangleDeclName(const NamedDecl *D);
-
   void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
   void mangleThunk(const CXXMethodDecl *MD,
                    const ThunkInfo &Thunk,
@@ -114,7 +126,8 @@
                      llvm::SmallVectorImpl<char> &);
   void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
                      llvm::SmallVectorImpl<char> &);
-  
+  void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
+
   void mangleInitDiscriminator() {
     Discriminator = 0;
   }





More information about the cfe-commits mailing list