Implement protected visibility. This partly implements PR1363. Linker
authorAnton Korobeynikov <asl@math.spbu.ru>
Sun, 29 Apr 2007 18:35:00 +0000 (18:35 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sun, 29 Apr 2007 18:35:00 +0000 (18:35 +0000)
should be taught to deal with protected symbols.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36565 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
docs/BytecodeFormat.html
docs/LangRef.html
include/llvm/GlobalValue.h
include/llvm/Target/TargetAsmInfo.h
lib/AsmParser/Lexer.l
lib/AsmParser/Lexer.l.cvs
lib/AsmParser/llvmAsmParser.y
lib/AsmParser/llvmAsmParser.y.cvs
lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Writer/Writer.cpp
lib/Target/TargetAsmInfo.cpp
lib/Target/X86/X86ATTAsmPrinter.cpp
lib/Target/X86/X86AsmPrinter.cpp
lib/VMCore/AsmWriter.cpp

index f479ca57b5f6ca56a09dedec25e0c2834143275d..1dc9c742bd91525d674c727f13c6e0d02bbd1f4c 100644 (file)
@@ -1044,7 +1044,7 @@ and can includes more information:</p>
     </tr>
     <tr>
       <td><a href="#bit">bit(10-12)</a></td>
-      <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+      <td class="td_left">Visibility style: 0=Default, 1=Hidden, 2=Protected.</td>
     </tr>
     <tr>
       <td><a href="#bit">bit(13-31)</a></td>
@@ -1506,7 +1506,7 @@ other fields will be present as the function is defined elsewhere.</li>
     </tr>
     <tr>
       <td><a href="#bit">bit(16-18)</a></td>
-      <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+      <td class="td_left">Visibility style: 0=Default, 1=Hidden, 2=Protected.</td>
     </tr>
     <tr>
       <td><a href="#bit">bit(19-31)</a></td>
index 67a2fc8a4ddf924f6390daf4c72d90b7e406f49a..58e0e3c5f39fcf7b73e3da3e2118b8d34ccfe5eb 100644 (file)
@@ -591,6 +591,13 @@ All Global Variables and Functions have one of the following visibility styles:
     directly.
   </dd>
 
+  <dt><b>"<tt>protected</tt>" - Protected style</b>:</dt>
+
+  <dd>On ELF, protected visibility indicates that the symbol will be placed in
+  the dynamic symbol table, but that references within the defining module will
+  bind to the local symbol. That is, the symbol cannot be overridden by another
+  module.
+  </dd>
 </dl>
 
 </div>
index 014cdbe82af2dd6f9b9e55904be2898d559fc130..4f6b1e6a9f96a1fcf23f431b0fc5dfac5bb1d86d 100644 (file)
@@ -43,7 +43,8 @@ public:
   /// @brief An enumeration for the kinds of visibility of global values.
   enum VisibilityTypes {
     DefaultVisibility = 0,  ///< The GV is visible
-    HiddenVisibility        ///< The GV is hidden
+    HiddenVisibility,       ///< The GV is hidden
+    ProtectedVisibility     ///< The GV is protected
   };
 
 protected:
@@ -58,7 +59,7 @@ protected:
   // Note: VC++ treats enums as signed, so an extra bit is required to prevent
   // Linkage and Visibility from turning into negative values.
   LinkageTypes Linkage : 5;   // The linkage of this global
-  unsigned Visibility : 1;    // The visibility style of this global
+  unsigned Visibility : 2;    // The visibility style of this global
   unsigned Alignment : 16;    // Alignment of this symbol, must be power of two
   std::string Section;        // Section to emit this into, empty mean default
 public:
@@ -74,6 +75,9 @@ public:
 
   VisibilityTypes getVisibility() const { return (VisibilityTypes)Visibility; }
   bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
+  bool hasProtectedVisibility() const {
+    return Visibility == ProtectedVisibility;
+  }
   void setVisibility(VisibilityTypes V) { Visibility = V; }
   
   bool hasSection() const { return !Section.empty(); }
index 60de43015dc35be89ffcc288a38e6c786f667b7c..b13a3fb50f4313faf54a06c940d03a2644275dbb 100644 (file)
@@ -256,7 +256,11 @@ namespace llvm {
     /// HiddenDirective - This directive, if non-null, is used to declare a
     /// global or function as having hidden visibility.
     const char *HiddenDirective;          // Defaults to "\t.hidden\t".
-    
+
+    /// ProtectedDirective - This directive, if non-null, is used to declare a
+    /// global or function as having protected visibility.
+    const char *ProtectedDirective;       // Defaults to "\t.protected\t".
+
     //===--- Dwarf Emission Directives -----------------------------------===//
 
     /// AbsoluteSectionOffsets - True if we should emit abolute section
@@ -523,6 +527,9 @@ namespace llvm {
     const char *getHiddenDirective() const {
       return HiddenDirective;
     }
+    const char *getProtectedDirective() const {
+      return ProtectedDirective;
+    }
     bool isAbsoluteSectionOffsets() const {
       return AbsoluteSectionOffsets;
     }
index 382ce24462a732dc6a9964faca8eda6882c875dc..b67f6ff102462e9ee7d71b7e22c62c6c2f2de13a 100644 (file)
@@ -206,6 +206,7 @@ appending       { return APPENDING; }
 dllimport       { return DLLIMPORT; }
 dllexport       { return DLLEXPORT; }
 hidden          { return HIDDEN; }
+protected       { return PROTECTED; }
 extern_weak     { return EXTERN_WEAK; }
 external        { return EXTERNAL; }
 thread_local    { return THREAD_LOCAL; }
index 382ce24462a732dc6a9964faca8eda6882c875dc..b67f6ff102462e9ee7d71b7e22c62c6c2f2de13a 100644 (file)
@@ -206,6 +206,7 @@ appending       { return APPENDING; }
 dllimport       { return DLLIMPORT; }
 dllexport       { return DLLEXPORT; }
 hidden          { return HIDDEN; }
+protected       { return PROTECTED; }
 extern_weak     { return EXTERN_WEAK; }
 external        { return EXTERNAL; }
 thread_local    { return THREAD_LOCAL; }
index c47b6fc6ea9062d2e65b7dbd2f78c8326c339c22..63f2261fa1177fcd94c0fa320c7c311d408d1f30 100644 (file)
@@ -1099,7 +1099,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %token NORETURN INREG SRET NOUNWIND
 
 // Visibility Styles
-%token DEFAULT HIDDEN
+%token DEFAULT HIDDEN PROTECTED
 
 %start Module
 %%
@@ -1180,9 +1180,10 @@ GVExternalLinkage
   ;
 
 GVVisibilityStyle
-  : /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
-  | DEFAULT   { $$ = GlobalValue::DefaultVisibility; }
-  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;  }
+  : /*empty*/ { $$ = GlobalValue::DefaultVisibility;   }
+  | DEFAULT   { $$ = GlobalValue::DefaultVisibility;   }
+  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;    }
+  | PROTECTED { $$ = GlobalValue::ProtectedVisibility; }
   ;
 
 FunctionDeclareLinkage
index c47b6fc6ea9062d2e65b7dbd2f78c8326c339c22..63f2261fa1177fcd94c0fa320c7c311d408d1f30 100644 (file)
@@ -1099,7 +1099,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %token NORETURN INREG SRET NOUNWIND
 
 // Visibility Styles
-%token DEFAULT HIDDEN
+%token DEFAULT HIDDEN PROTECTED
 
 %start Module
 %%
@@ -1180,9 +1180,10 @@ GVExternalLinkage
   ;
 
 GVVisibilityStyle
-  : /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
-  | DEFAULT   { $$ = GlobalValue::DefaultVisibility; }
-  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;  }
+  : /*empty*/ { $$ = GlobalValue::DefaultVisibility;   }
+  | DEFAULT   { $$ = GlobalValue::DefaultVisibility;   }
+  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;    }
+  | PROTECTED { $$ = GlobalValue::ProtectedVisibility; }
   ;
 
 FunctionDeclareLinkage
index 99aac056ff3bc7fea80e10b0b11698789986b656..e75f0fcd6108af106b368e3248df0bfe7b8477ad 100644 (file)
@@ -1532,6 +1532,7 @@ void BytecodeReader::ParseFunctionBody(Function* F) {
   switch (VisibilityID) {
   case 0: Visibility = GlobalValue::DefaultVisibility; break;
   case 1: Visibility = GlobalValue::HiddenVisibility; break;
+  case 2: Visibility = GlobalValue::ProtectedVisibility; break;
   default:
    error("Unknown visibility type: " + utostr(VisibilityID));
    Visibility = GlobalValue::DefaultVisibility;
@@ -1767,6 +1768,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
     switch (VisibilityID) {
     case 0: Visibility = GlobalValue::DefaultVisibility; break;
     case 1: Visibility = GlobalValue::HiddenVisibility; break;
+    case 2: Visibility = GlobalValue::ProtectedVisibility; break;
     default:
       error("Unknown visibility type: " + utostr(VisibilityID));
       Visibility = GlobalValue::DefaultVisibility;
index f1c6f6c56190e2abec870deea131fb16ebaf1245..b4a26916008a3aa2e1cba4bb32c9a7af8176f9a1 100644 (file)
@@ -957,8 +957,9 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
 static unsigned getEncodedVisibility(const GlobalValue *GV) {
   switch (GV->getVisibility()) {
   default: assert(0 && "Invalid visibility!");
-  case GlobalValue::DefaultVisibility: return 0;
-  case GlobalValue::HiddenVisibility:  return 1;
+  case GlobalValue::DefaultVisibility:   return 0;
+  case GlobalValue::HiddenVisibility:    return 1;
+  case GlobalValue::ProtectedVisibility: return 2;
   }
 }
 
index 8deda9fe6a58f6fc70104311ee9196f7461c36f5..37ab073ffcddb2d93defe5cb819998fa7feba673 100644 (file)
@@ -74,6 +74,7 @@ TargetAsmInfo::TargetAsmInfo() :
   UsedDirective(0),
   WeakRefDirective(0),
   HiddenDirective("\t.hidden\t"),
+  ProtectedDirective("\t.protected\t"),
   AbsoluteSectionOffsets(false),
   HasLEB128(false),
   HasDotLoc(false),
index 03a22865e2ce8378a6689229b20ab715f23181cf..634f41b9200abfe51e6b1252d322a1e03dd69ffb 100755 (executable)
@@ -125,9 +125,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     }
     break;
   }
-  if (F->hasHiddenVisibility())
+  if (F->hasHiddenVisibility()) {
     if (const char *Directive = TAI->getHiddenDirective())
       O << Directive << CurrentFnName << "\n";
+  } else if (F->hasProtectedVisibility()) {
+    if (const char *Directive = TAI->getProtectedDirective())
+      O << Directive << CurrentFnName << "\n";
+  }
 
   if (Subtarget->isTargetELF())
     O << "\t.type " << CurrentFnName << ",@function\n";
@@ -322,7 +326,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       if (isCallOp && isa<Function>(GV)) {
         if (printGOT(TM, Subtarget)) {
           // Assemble call via PLT for non-local symbols
-          if (!GV->hasHiddenVisibility() || GV->isDeclaration())
+          if (!(GV->hasHiddenVisibility() || GV->hasProtectedVisibility()) ||
+              GV->isDeclaration())
             O << "@PLT";
         }
         if (Subtarget->isTargetCygMing() && GV->isDeclaration())
index 76037f13bd5b029e0ef48d29202cae92583b58e1..7e7dc8861a7c48206d41ebd03ea3a43a754f1906 100644 (file)
@@ -155,9 +155,14 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
     unsigned Size = TD->getTypeSize(Type);
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
-    if (I->hasHiddenVisibility())
+    if (I->hasHiddenVisibility()) {
       if (const char *Directive = TAI->getHiddenDirective())
         O << Directive << name << "\n";
+    } else if (I->hasProtectedVisibility()) {
+      if (const char *Directive = TAI->getProtectedDirective())
+        O << Directive << name << "\n";
+    }
+    
     if (Subtarget->isTargetELF())
       O << "\t.type " << name << ",@object\n";
     
index ac68e8d32fb942e6c1a310cb695677d1a9680f8a..3a065b0cdfe806b62d76af258bbf21cd802b553b 100644 (file)
@@ -886,6 +886,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
     default: assert(0 && "Invalid visibility style!");
     case GlobalValue::DefaultVisibility: break;
     case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+    case GlobalValue::ProtectedVisibility: Out << "protected "; break;
     }
   }
 
@@ -914,6 +915,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
   default: assert(0 && "Invalid visibility style!");
   case GlobalValue::DefaultVisibility: break;
   case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+  case GlobalValue::ProtectedVisibility: Out << "protected "; break;
   }
 
   Out << "alias ";
@@ -998,6 +1000,7 @@ void AssemblyWriter::printFunction(const Function *F) {
     default: assert(0 && "Invalid visibility style!");
     case GlobalValue::DefaultVisibility: break;
     case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+    case GlobalValue::ProtectedVisibility: Out << "protected "; break;
     }
   }