diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -123,8 +123,11 @@ void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); - void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &); - void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); + void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, + bool includePrefixByte = true, + bool includeCategoryNamespace = true); + void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, + raw_ostream &); virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2516,7 +2516,7 @@ } void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { - Context.mangleObjCMethodName(MD, Out); + Context.mangleObjCMethodNameAsSourceName(MD, Out); } static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty, diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -175,7 +175,7 @@ const TargetInfo &TI = Context.getTargetInfo(); if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) { if (const ObjCMethodDecl *OMD = dyn_cast(D)) - mangleObjCMethodName(OMD, Out); + mangleObjCMethodNameAsSourceName(OMD, Out); else mangleCXXName(GD, Out); return; @@ -192,7 +192,7 @@ if (!MCXX) Out << D->getIdentifier()->getName(); else if (const ObjCMethodDecl *OMD = dyn_cast(D)) - mangleObjCMethodName(OMD, Out); + mangleObjCMethodNameAsSourceName(OMD, Out); else mangleCXXName(GD, Out); @@ -275,7 +275,7 @@ SmallString<64> Buffer; llvm::raw_svector_ostream Stream(Buffer); if (const ObjCMethodDecl *Method = dyn_cast(DC)) { - mangleObjCMethodName(Method, Stream); + mangleObjCMethodNameAsSourceName(Method, Stream); } else { assert((isa(DC) || isa(DC)) && "expected a NamedDecl or BlockDecl"); @@ -304,29 +304,38 @@ mangleFunctionBlock(*this, Buffer, BD, Out); } -void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, - raw_ostream &OS) { - const ObjCContainerDecl *CD = - dyn_cast(MD->getDeclContext()); - assert (CD && "Missing container decl in GetNameForMethod"); +void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, + raw_ostream &OS, + bool includePrefixByte, + bool includeCategoryNamespace) { + // \01+[ContainerName(CategoryName) SelectorName] + if (includePrefixByte) { + OS << '\01'; + } OS << (MD->isInstanceMethod() ? '-' : '+') << '['; - if (const ObjCCategoryImplDecl *CID = dyn_cast(CD)) { + if (const auto *CID = dyn_cast(MD->getDeclContext())) { OS << CID->getClassInterface()->getName(); - OS << '(' << *CID << ')'; - } else { + if (includeCategoryNamespace) { + OS << '(' << *CID << ')'; + } + } else if (const auto *CD = + dyn_cast(MD->getDeclContext())) { OS << CD->getName(); + } else { + llvm_unreachable("Unexpected ObjC method decl context"); } OS << ' '; MD->getSelector().print(OS); OS << ']'; } -void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &Out) { +void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, + raw_ostream &Out) { SmallString<64> Name; llvm::raw_svector_ostream OS(Name); - mangleObjCMethodNameWithoutSize(MD, OS); + mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false, + /*includeCategoryNamespace=*/true); Out << OS.str().size() << OS.str(); } @@ -352,7 +361,8 @@ if (writeFuncOrVarName(VD, FrontendBufOS)) return true; } else if (auto *MD = dyn_cast(D)) { - MC->mangleObjCMethodNameWithoutSize(MD, OS); + MC->mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false, + /*includeCategoryNamespace=*/true); return false; } else if (auto *ID = dyn_cast(D)) { writeObjCClassName(ID, FrontendBufOS); diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1323,7 +1323,7 @@ } void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { - Context.mangleObjCMethodName(MD, Out); + Context.mangleObjCMethodNameAsSourceName(MD, Out); } void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -20,6 +20,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/CodeGenOptions.h" @@ -924,13 +925,6 @@ llvm::StringMap NSConstantStringMap; - /// GetNameForMethod - Return a name for the given method. - /// \param[out] NameOut - The return value. - void GetNameForMethod(const ObjCMethodDecl *OMD, - const ObjCContainerDecl *CD, - SmallVectorImpl &NameOut, - bool ignoreCategoryNamespace = false); - /// GetMethodVarName - Return a unique constant for the given /// selector's name. The return value has type char *. llvm::Constant *GetMethodVarName(Selector Sel); @@ -1086,7 +1080,7 @@ public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : - CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { } + CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()), Mangler(cgm.getContext().createMangleContext()) { } bool isNonFragileABI() const { return ObjCABI == 2; @@ -1127,6 +1121,7 @@ private: void fillRunSkipBlockVars(CodeGenModule &CGM, const CGBlockInfo &blockInfo); + std::unique_ptr Mangler; }; namespace { @@ -4008,7 +4003,9 @@ Method = GenerateDirectMethod(OMD, CD); } else { SmallString<256> Name; - GetNameForMethod(OMD, CD, Name); + llvm::raw_svector_ostream OS(Name); + Mangler->mangleObjCMethodName(OMD, OS, /*includePrefixByte=*/true, + /*includeCategoryNamespace=*/true); CodeGenTypes &Types = CGM.getTypes(); llvm::FunctionType *MethodTy = @@ -4061,7 +4058,9 @@ I->second = Fn; } else { SmallString<256> Name; - GetNameForMethod(OMD, CD, Name, /*ignoreCategoryNamespace*/ true); + llvm::raw_svector_ostream OS(Name); + Mangler->mangleObjCMethodName(OMD, OS, /*includePrefixByte=*/true, + /*includeCategoryNamespace=*/false); Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage, Name.str(), &CGM.getModule()); @@ -5715,21 +5714,6 @@ return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); } -void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, - const ObjCContainerDecl *CD, - SmallVectorImpl &Name, - bool ignoreCategoryNamespace) { - llvm::raw_svector_ostream OS(Name); - assert (CD && "Missing container decl in GetNameForMethod"); - OS << '\01' << (D->isInstanceMethod() ? '-' : '+') - << '[' << CD->getName(); - if (!ignoreCategoryNamespace) - if (const ObjCCategoryImplDecl *CID = - dyn_cast(D->getDeclContext())) - OS << '(' << *CID << ')'; - OS << ' ' << D->getSelector().getAsString() << ']'; -} - void CGObjCMac::FinishModule() { EmitModuleInfo();