diff options
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 44 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.h | 17 |
6 files changed, 67 insertions, 5 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index f49b6ee18b..dcae95f3de 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -791,9 +791,10 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, 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); diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 85222fe9db..be4256a691 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -230,6 +230,10 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 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) { diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 222dcc4b8f..73de0fd773 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -37,6 +37,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) LLVMPointerWidth = Target.getPointerWidth(0); Exceptions = getContext().getLangOptions().Exceptions; CatchUndefined = getContext().getLangOptions().CatchUndefined; + CGM.getMangleContext().startNewFunction(); } ASTContext &CodeGenFunction::getContext() const { diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index e225462fac..b14c35f384 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -413,6 +413,7 @@ public: 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); diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 46a9f6ce82..88e4c647c8 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -102,6 +102,7 @@ public: 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 @@ void CXXNameMangler::mangleNumber(int64_t Number) { 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 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { 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 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { 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 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 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) { diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index da3626fc5d..04f5dd6b21 100644 --- a/lib/CodeGen/Mangle.h +++ b/lib/CodeGen/Mangle.h @@ -26,6 +26,7 @@ namespace clang { class ASTContext; + class BlockDecl; class CXXConstructorDecl; class CXXDestructorDecl; class CXXMethodDecl; @@ -73,6 +74,8 @@ class MangleContext { 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 @@ public: 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 @@ public: 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 @@ public: 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; } |