From: Daniel Dunbar Date: Tue, 7 Apr 2009 05:48:37 +0000 (+0000) Subject: Various fixes to symbols used for Obj-C x86_64 metadata. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ab187a49a42de6d351248d8a6e0206e39743a0c;p=clang Various fixes to symbols used for Obj-C x86_64 metadata. - Changed method names to match gcc (categories names still aren't mangled in). - Expose correct name for class and metadata symbols (although -fvisibility=hidden isn't yet correct). - Remove several things from llvm.used that didn't need to be there (I suspect this can still be trimmed). - Don't use asm-prefix extension for _objc_empty_{cache,vtable} (not needed). - Hide EH type class info with -fvisibility=hidden - Change setGlobal[Option]Visibility to not change the visibility of functions with internal linkage. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68510 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 7f3645556b..e62bf2f3fc 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -753,8 +753,11 @@ LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) { if(const FunctionDecl *FD = dyn_cast(CurFuncDecl)) { FunctionName = CGM.getMangledName(FD); } else { - // Just get the mangled name. + // Just get the mangled name; skipping the asm prefix if it + // exists. FunctionName = CurFn->getName(); + if (FunctionName[0] == '\01') + FunctionName = FunctionName.substr(1, std::string::npos); } GlobalVarName += FunctionName; diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 426ad8c0f5..cf2d8da022 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -768,7 +768,8 @@ private: /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name); + llvm::GlobalVariable *GetClassGlobal(const std::string &Name, + bool AddToUsed = true); /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class. @@ -795,7 +796,15 @@ private: /// GetInterfaceEHType - Get the ehtype for the given Objective-C /// interface. The return value has type EHTypePtrTy. llvm::Value *GetInterfaceEHType(const ObjCInterfaceType *IT); + + const char *getMetaclassSymbolPrefix() const { + return "OBJC_METACLASS_$_"; + } + const char *getClassSymbolPrefix() const { + return "OBJC_CLASS_$_"; + } + public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); // FIXME. All stubs for now! @@ -3034,8 +3043,8 @@ llvm::Constant * void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, const ObjCContainerDecl *CD, std::string &NameOut) { - // FIXME: Find the mangling GCC uses. - NameOut = (D->isInstanceMethod() ? "-" : "+"); + NameOut = '\01'; + NameOut += (D->isInstanceMethod() ? '-' : '+'); NameOut += '['; assert (CD && "Missing container decl in GetNameForMethod"); NameOut += CD->getNameAsString(); @@ -4128,7 +4137,6 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( CLASS_RO_GV->setAlignment( CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassRonfABITy)); CLASS_RO_GV->setSection("__DATA, __objc_const"); - UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; } @@ -4166,7 +4174,6 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassnfABITy)); if (HiddenVisibility) GV->setVisibility(llvm::GlobalValue::HiddenVisibility); - UsedGlobals.push_back(GV); return GV; } @@ -4178,18 +4185,16 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { false, llvm::GlobalValue::ExternalLinkage, 0, - "\01__objc_empty_cache", + "_objc_empty_cache", &CGM.getModule()); - UsedGlobals.push_back(ObjCEmptyCacheVar); ObjCEmptyVtableVar = new llvm::GlobalVariable( ObjCTypes.ImpnfABITy, false, llvm::GlobalValue::ExternalLinkage, 0, - "\01__objc_empty_vtable", + "_objc_empty_vtable", &CGM.getModule()); - UsedGlobals.push_back(ObjCEmptyVtableVar); } assert(ID->getClassInterface() && "CGObjCNonFragileABIMac::GenerateClass - class is 0"); @@ -4197,8 +4202,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassnfABITy); uint32_t InstanceSize = InstanceStart; uint32_t flags = CLS_META; - std::string ObjCMetaClassName("\01_OBJC_METACLASS_$_"); - std::string ObjCClassName("\01_OBJC_CLASS_$_"); + std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); + std::string ObjCClassName(getClassSymbolPrefix()); llvm::GlobalVariable *SuperClassGV, *IsAGV; @@ -4209,17 +4214,17 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { // class is root flags |= CLS_ROOT; SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); - IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); + IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName, false); } else { // Has a root. Current class is not a root. const ObjCInterfaceDecl *Root = ID->getClassInterface(); while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) Root = Super; - IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); + IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString(), false); // work on super class metadata symbol. std::string SuperClassName = ObjCMetaClassName + ID->getClassInterface()->getSuperClass()->getNameAsString(); - SuperClassGV = GetClassGlobal(SuperClassName); + SuperClassGV = GetClassGlobal(SuperClassName, false); } llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, InstanceStart, @@ -4228,7 +4233,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *MetaTClass = BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden); - + // Metadata for the class flags = CLS; if (classIsHidden) @@ -4280,6 +4285,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *ClassMD = BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden); + UsedGlobals.push_back(ClassMD); DefinedClasses.push_back(ClassMD); } @@ -4331,7 +4337,8 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) const char *Prefix = "\01l_OBJC_$_CATEGORY_"; std::string ExtCatName(Prefix + Interface->getNameAsString()+ "_$_" + OCD->getNameAsString()); - std::string ExtClassName("\01_OBJC_CLASS_$_" + Interface->getNameAsString()); + std::string ExtClassName(getClassSymbolPrefix() + + Interface->getNameAsString()); std::vector Values(6); Values[0] = GetClassName(OCD->getIdentifier()); @@ -5011,14 +5018,16 @@ CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend( } llvm::GlobalVariable * -CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { +CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, + bool AddToUsed) { llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); if (!GV) { GV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, llvm::GlobalValue::ExternalLinkage, 0, Name, &CGM.getModule()); - UsedGlobals.push_back(GV); + if (AddToUsed) + UsedGlobals.push_back(GV); } return GV; @@ -5031,7 +5040,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; if (!Entry) { - std::string ClassName("\01_OBJC_CLASS_$_" + ID->getNameAsString()); + std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); Entry = new llvm::GlobalVariable(ObjCTypes.ClassnfABIPtrTy, false, @@ -5063,8 +5072,8 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, if (Entry) return Builder.CreateLoad(Entry, false, "tmp"); - std::string MetaClassName("\01_OBJC_METACLASS_$_" + ID->getNameAsString()); - llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); + std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); + llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName, false); Entry = new llvm::GlobalVariable(ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::InternalLinkage, @@ -5545,7 +5554,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) { if (Entry) return Entry; - std::string ClassName("\01_OBJC_CLASS_$_" + ID->getNameAsString()); + std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); std::string VTableName = "objc_ehtype_vtable"; llvm::GlobalVariable *VTableGV = CGM.getModule().getGlobalVariable(VTableName); @@ -5559,7 +5568,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) { std::vector Values(3); Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1); Values[1] = GetClassName(ID->getIdentifier()); - Values[2] = GetClassGlobal(ClassName); + Values[2] = GetClassGlobal(ClassName, false); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); Entry = @@ -5569,6 +5578,10 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) { (std::string("OBJC_EHTYPE_$_") + ID->getIdentifier()->getName()), &CGM.getModule()); + if (CGM.getLangOptions().getVisibilityMode() == + LangOptions::HiddenVisibility) + Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); + Entry->setSection("__DATA,__datacoal_nt,coalesced"); return Entry; } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 379ff9b424..1dd2c4d67f 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -99,6 +99,10 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, /// GlobalValue according to the given clang AST visibility value. static void setGlobalVisibility(llvm::GlobalValue *GV, VisibilityAttr::VisibilityTypes Vis) { + // Do not change the visibility of internal definitions. + if (GV->hasInternalLinkage()) + return; + switch (Vis) { default: assert(0 && "Unknown visibility!"); case VisibilityAttr::DefaultVisibility: @@ -115,6 +119,10 @@ static void setGlobalVisibility(llvm::GlobalValue *GV, static void setGlobalOptionVisibility(llvm::GlobalValue *GV, LangOptions::VisibilityMode Vis) { + // Do not change the visibility of internal definitions. + if (GV->hasInternalLinkage()) + return; + switch (Vis) { default: assert(0 && "Unknown visibility!"); case LangOptions::NonVisibility: diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m new file mode 100644 index 0000000000..99372b829f --- /dev/null +++ b/test/CodeGenObjC/metadata_symbols.m @@ -0,0 +1,46 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -emit-llvm -o %t %s && + +// RUN: grep '@"OBJC_METACLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && +// RUN: grep '@"OBJC_CLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && +// RUN: grep '@"OBJC_EHTYPE_$_EH" = weak global .*section "__DATA,__datacoal_nt,coalesced"' %t && +// RUN: grep -F 'define internal void @"\01-[A im0]"' %t && +// FIXME: Should include category name. +// RUN: grep -F 'define internal void @"\01-[A im1]"' %t && + +// RUN: clang-cc -fvisibility=hidden -triple x86_64-apple-darwin9 -emit-llvm -o %t %s && + +// FIXME: This is wrong, should be hidden +// RUN: grep '@"OBJC_METACLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && +// FIXME: This is wrong, should be hidden +// RUN: grep '@"OBJC_CLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && +// RUN: grep '@"OBJC_EHTYPE_$_EH" = weak hidden global .*section "__DATA,__datacoal_nt,coalesced"' %t && +// RUN: grep -F 'define internal void @"\01-[A im0]"' %t && +// FIXME: Should include category name. +// RUN: grep -F 'define internal void @"\01-[A im1]"' %t && + +// RUN: true + +@interface A +@end + +@implementation A +-(void) im0 { +} +@end + +@implementation A (Cat) +-(void) im1 { +} +@end + +@interface EH +@end + +void f1(); + +void f0(id x) { + @try { + f1(); + } @catch (EH *x) { + } +}