aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGBlocks.cpp5
-rw-r--r--lib/CodeGen/CGCXX.cpp4
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp1
-rw-r--r--lib/CodeGen/CodeGenModule.h1
-rw-r--r--lib/CodeGen/Mangle.cpp44
-rw-r--r--lib/CodeGen/Mangle.h17
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;
}