diff --git a/include/llvm/Target/DarwinTargetAsmInfo.h b/include/llvm/Target/DarwinTargetAsmInfo.h index 0ed9b387037..4abf4b7cfd1 100644 --- a/include/llvm/Target/DarwinTargetAsmInfo.h +++ b/include/llvm/Target/DarwinTargetAsmInfo.h @@ -22,6 +22,7 @@ namespace llvm { class GlobalValue; class GlobalVariable; class Type; + class Mangler; struct DarwinTargetAsmInfo: public virtual TargetAsmInfo { const Section* TextCoalSection; @@ -33,6 +34,8 @@ namespace llvm { virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, SectionKind::Kind kind) const; + virtual bool emitUsedDirectiveFor(const GlobalValue *GV, + Mangler *Mang) const; const Section* MergeableConstSection(const GlobalVariable *GV) const; const Section* MergeableConstSection(const Type *Ty) const; const Section* MergeableStringSection(const GlobalVariable *GV) const; diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index bbb58527eb6..589c9a6efc9 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -100,6 +100,7 @@ namespace llvm { class CallInst; class GlobalValue; class Type; + class Mangler; class Section { friend class TargetAsmInfo; @@ -220,9 +221,9 @@ namespace llvm { /// have names in the .o file. This is often "." or "L". const char *PrivateGlobalPrefix; // Defaults to "." - /// LessPrivateGlobalPrefix - This prefix is used for some Objective C - /// metadata symbols that should be passed through the assembler but be - /// removed by the linker. This is "l" on Darwin. + /// LessPrivateGlobalPrefix - This prefix is used for symbols that should + /// be passed through the assembler but be removed by the linker. This + /// is "l" on Darwin, currently used for some ObjC metadata. const char *LessPrivateGlobalPrefix; // Defaults to "" /// JumpTableSpecialLabelPrefix - If not null, a extra (dead) label is @@ -543,6 +544,13 @@ namespace llvm { return false; } + /// emitUsedDirectiveFor - This hook allows targets to selectively decide + /// not to emit the UsedDirective for some symbols in llvm.used. + virtual bool emitUsedDirectiveFor(const GlobalValue *GV, + Mangler *Mang) const { + return (GV!=0); + } + /// PreferredEHDataFormat - This hook allows the target to select data /// format used for encoding pointers in exception handling data. Reason is /// 0 for data, 1 for code labels, 2 for function pointers. Global is true diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index f041f3be56f..98f4b7d13cd 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -451,10 +451,9 @@ const GlobalValue * AsmPrinter::findGlobalValue(const Constant *CV) { } /// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each -/// global in the specified llvm.used list as being used with this directive. -/// Internally linked data beginning with the PrivateGlobalPrefix or the -/// LessPrivateGlobalPrefix does not have the directive emitted (this -/// occurs in ObjC metadata). +/// global in the specified llvm.used list for which emitUsedDirectiveFor +/// is true, as being used with this directive. + void AsmPrinter::EmitLLVMUsedList(Constant *List) { const char *Directive = TAI->getUsedDirective(); @@ -464,17 +463,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) { for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { const GlobalValue *GV = findGlobalValue(InitList->getOperand(i)); - if (GV) { - if (GV->hasInternalLinkage() && !isa(GV) && - ((strlen(TAI->getPrivateGlobalPrefix()) != 0 && - Mang->getValueName(GV) - .substr(0,strlen(TAI->getPrivateGlobalPrefix())) == - TAI->getPrivateGlobalPrefix()) || - (strlen(TAI->getLessPrivateGlobalPrefix()) != 0 && - Mang->getValueName(GV) - .substr(0,strlen(TAI->getLessPrivateGlobalPrefix())) == - TAI->getLessPrivateGlobalPrefix()))) - continue; + if (TAI->emitUsedDirectiveFor(GV, Mang)) { O << Directive; EmitConstantValueOnly(InitList->getOperand(i)); O << '\n'; diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp index 749cb717943..2fc1d28d2b6 100644 --- a/lib/Target/DarwinTargetAsmInfo.cpp +++ b/lib/Target/DarwinTargetAsmInfo.cpp @@ -17,6 +17,7 @@ #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Mangler.h" #include "llvm/Target/DarwinTargetAsmInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetData.h" @@ -50,6 +51,26 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) { SectionFlags::Writeable); } +/// emitUsedDirectiveFor - On Darwin, internally linked data beginning with +/// the PrivateGlobalPrefix or the LessPrivateGlobalPrefix does not have the +/// directive emitted (this occurs in ObjC metadata). + +bool +DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV, + Mangler *Mang) const { + if (GV==0) + return false; + if (GV->hasInternalLinkage() && !isa(GV) && + ((strlen(getPrivateGlobalPrefix()) != 0 && + Mang->getValueName(GV).substr(0,strlen(getPrivateGlobalPrefix())) == + getPrivateGlobalPrefix()) || + (strlen(getLessPrivateGlobalPrefix()) != 0 && + Mang->getValueName(GV).substr(0,strlen(getLessPrivateGlobalPrefix())) == + getLessPrivateGlobalPrefix()))) + return false; + return true; +} + const Section* DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { SectionKind::Kind Kind = SectionKindForGlobal(GV);