]> granicus.if.org Git - clang/commitdiff
Implement -fvisibility.
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 3 Apr 2009 03:28:57 +0000 (03:28 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 3 Apr 2009 03:28:57 +0000 (03:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68369 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.h
include/clang/Driver/Options.def
lib/CodeGen/CodeGenModule.cpp
test/CodeGen/visibility-option.c [new file with mode: 0644]
tools/clang-cc/clang-cc.cpp

index f16b403828164dfef44e528621821175b52ae5c2..5f4c8f41314861e496636ad50d485b8a7c6672c2 100644 (file)
@@ -64,14 +64,19 @@ public:
 
   unsigned HeinousExtensions : 1; // Extensions that we really don't like and
                                   // may be ripped out at any time.
+
 private:
   unsigned GC : 2; // Objective-C Garbage Collection modes.  We declare
                    // this enum as unsigned because MSVC insists on making enums
                    // signed.  Set/Query this value using accessors.  
+  unsigned SymbolVisibility  : 3; // Symbol's visibility.
+
 public:  
   unsigned InstantiationDepth;    // Maximum template instantiation depth.
 
   enum GCMode { NonGC, GCOnly, HybridGC };
+  enum VisibilityMode {NonVisibility, DefaultVisibility, ProtectedVisibility, 
+                       HiddenVisibility, InternalVisibility };
   
   LangOptions() {
     Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0;
@@ -97,6 +102,9 @@ public:
   
   GCMode getGCMode() const { return (GCMode) GC; }
   void setGCMode(GCMode m) { GC = (unsigned) m; }
+
+  VisibilityMode getVisibilityMode() const { return (VisibilityMode) SymbolVisibility; }
+  void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
   
   /// Emit - Emit this LangOptions object to bitcode.
   void Emit(llvm::Serializer& S) const;
index 33b24f63dd7c4b310ddca9557c40066d15016462..c5ebb9abc0f2db084b25b44478b5824e0d2008ac 100644 (file)
@@ -451,6 +451,7 @@ OPTION("-ftraditional", ftraditional, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-ftrapv", ftrapv, Flag, clang_f_Group, INVALID, "", 0, 0, 0)
 OPTION("-funwind-tables", funwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fverbose-asm", fverbose_asm, Flag, f_Group, INVALID, "", 0, 0, 0)
+OPTION("-fvisibility=", f_visibility_EQ, Joined, clang_f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fwritable-strings", fwritable_strings, Flag, clang_f_Group, INVALID, "", 0, 0, 0)
 OPTION("-fzero-initialized-in-bss", fzero_initialized_in_bss, Flag, f_Group, INVALID, "", 0, 0, 0)
 OPTION("-f", f, Joined, f_Group, INVALID, "", 0, 0, 0)
index 1132c3f721dfcd53e50268ceebe0c43aec501c83..1bf73db177c4d3061645e8752096b45d0fec6ca0 100644 (file)
@@ -113,6 +113,25 @@ static void setGlobalVisibility(llvm::GlobalValue *GV,
   }
 }
 
+static void setGlobalOptionVisibility(llvm::GlobalValue *GV,
+                                      LangOptions::VisibilityMode Vis) {
+  switch (Vis) {
+  default: assert(0 && "Unknown visibility!");
+  case LangOptions::NonVisibility:
+    break;
+  case LangOptions::DefaultVisibility:
+    GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
+    break;
+  case LangOptions::HiddenVisibility:
+    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    break;
+  case LangOptions::ProtectedVisibility:
+    GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
+    break;
+  }
+}
+                                      
+
 /// \brief Retrieves the mangled name for the given declaration.
 ///
 /// If the given declaration requires a mangled name, returns an
@@ -247,7 +266,8 @@ void CodeGenModule::SetGlobalValueAttributes(const Decl *D,
   // -fvisibility, and private_extern.
   if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
     setGlobalVisibility(GV, attr->getVisibility());
-  // FIXME: else handle -fvisibility
+  else
+    setGlobalOptionVisibility(GV, getLangOptions().getVisibilityMode());
 
   if (const SectionAttr *SA = D->getAttr<SectionAttr>())
     GV->setSection(SA->getName());
@@ -751,7 +771,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
 
   if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
     setGlobalVisibility(GV, attr->getVisibility());
-  // FIXME: else handle -fvisibility
+  else
+    setGlobalOptionVisibility(GV, getLangOptions().getVisibilityMode());
 
   // Set the llvm linkage type as appropriate.
   if (D->getStorageClass() == VarDecl::Static)
diff --git a/test/CodeGen/visibility-option.c b/test/CodeGen/visibility-option.c
new file mode 100644 (file)
index 0000000..41b77ca
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: clang-cc -fvisibility=hidden -emit-llvm -o - %s | grep -e "hidden" | count 2
+
+int Global = 10; 
+
+void Func() {}
+
index de1940938833d14a667f3710d2c06831a330635a..e6dac4309ba0cbc7a1e74cc2dccaa1c0a5f9065f 100644 (file)
@@ -764,6 +764,28 @@ void InitializeGCMode(LangOptions &Options) {
     Options.setGCMode(LangOptions::HybridGC);
 }
 
+static llvm::cl::opt<std::string>
+SymbolVisibility("fvisibility",
+  llvm::cl::desc("Set the default visibility to the specific option"));
+
+void InitializeSymbolVisibility(LangOptions &Options) {
+  if (SymbolVisibility.empty())
+    return;
+  std::string Visibility = SymbolVisibility;
+  const char *vkind = Visibility.c_str();
+  if (!strcmp(vkind, "default"))
+    Options.setVisibilityMode(LangOptions::DefaultVisibility);
+  else if (!strcmp(vkind, "protected"))
+    Options.setVisibilityMode(LangOptions::ProtectedVisibility);
+  else if (!strcmp(vkind, "hidden"))
+    Options.setVisibilityMode(LangOptions::HiddenVisibility);
+  else if (!strcmp(vkind, "internal"))
+    Options.setVisibilityMode(LangOptions::InternalVisibility);
+  else
+    fprintf(stderr,
+            "-fvisibility only valid for default|protected|hidden|internal\n");
+}
+
 static llvm::cl::opt<bool>
 OverflowChecking("ftrapv",
            llvm::cl::desc("Trap on integer overflow"),
@@ -1770,6 +1792,7 @@ int main(int argc, char **argv) {
     LangKind LK = GetLanguage(InFile);
     InitializeLangOptions(LangInfo, LK);
     InitializeGCMode(LangInfo);
+    InitializeSymbolVisibility(LangInfo);
     InitializeOverflowChecking(LangInfo);
     InitializeLanguageStandard(LangInfo, LK, Target.get());