From: Fariborz Jahanian Date: Fri, 3 Apr 2009 03:28:57 +0000 (+0000) Subject: Implement -fvisibility. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7cd2e93125e2f3b6ca01b24ed0c3fd7e94683fd9;p=clang Implement -fvisibility. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68369 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index f16b403828..5f4c8f4131 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -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; diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index 33b24f63dd..c5ebb9abc0 100644 --- a/include/clang/Driver/Options.def +++ b/include/clang/Driver/Options.def @@ -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) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 1132c3f721..1bf73db177 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -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()) setGlobalVisibility(GV, attr->getVisibility()); - // FIXME: else handle -fvisibility + else + setGlobalOptionVisibility(GV, getLangOptions().getVisibilityMode()); if (const SectionAttr *SA = D->getAttr()) GV->setSection(SA->getName()); @@ -751,7 +771,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { if (const VisibilityAttr *attr = D->getAttr()) 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 index 0000000000..41b77cab1d --- /dev/null +++ b/test/CodeGen/visibility-option.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -fvisibility=hidden -emit-llvm -o - %s | grep -e "hidden" | count 2 + +int Global = 10; + +void Func() {} + diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index de19409388..e6dac4309b 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -764,6 +764,28 @@ void InitializeGCMode(LangOptions &Options) { Options.setGCMode(LangOptions::HybridGC); } +static llvm::cl::opt +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 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());