diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-04-14 06:00:08 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-04-14 06:00:08 +0000 |
commit | 04d4078425614bf9fd58d606335c1f5f74ee7fa4 (patch) | |
tree | 50baa3264e6c2b836c5a99fc45b70a0c74923f82 /lib/CodeGen | |
parent | 9f9427999cf69b3b89cd0ed3be16ed27a1c282c7 (diff) |
Clean up handling of visibility.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69027 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 128 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 8 |
3 files changed, 59 insertions, 115 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index c69f5937d0..153c8681a0 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -440,8 +440,6 @@ protected: llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, bool ForStrongLayout); - bool IsClassHidden(const ObjCInterfaceDecl *ID); - void BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, const llvm::StructLayout *Layout, const RecordDecl *RD, @@ -1441,23 +1439,6 @@ enum ClassFlags { eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> }; -bool CGObjCCommonMac::IsClassHidden(const ObjCInterfaceDecl *ID) { - if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) { - switch (attr->getVisibility()) { - default: - assert(0 && "Unknown visibility"); - return false; - case VisibilityAttr::DefaultVisibility: - case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here? - return false; - case VisibilityAttr::HiddenVisibility: - return true; - } - } else - return (CGM.getLangOptions().getVisibilityMode() == - LangOptions::HiddenVisibility); -} - /* struct _objc_class { Class isa; @@ -1494,7 +1475,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy); // FIXME: Set CXX-structors flag. - if (IsClassHidden(ID->getClassInterface())) + if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) Flags |= eClassFlags_Hidden; std::vector<llvm::Constant*> InstanceMethods, ClassMethods; @@ -1571,7 +1552,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, unsigned Flags = eClassFlags_Meta; unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassTy); - if (IsClassHidden(ID->getClassInterface())) + if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) Flags |= eClassFlags_Hidden; std::vector<llvm::Constant*> Values(12); @@ -4226,7 +4207,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *SuperClassGV, *IsAGV; - bool classIsHidden = IsClassHidden(ID->getClassInterface()); + bool classIsHidden = + CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden; if (classIsHidden) flags |= OBJC2_CLS_HIDDEN; if (!ID->getClassInterface()->getSuperClass()) { @@ -4547,13 +4529,10 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy)); // @private and @package have hidden visibility. bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public || - Ivar->getAccessControl() == ObjCIvarDecl::Protected); - if (!globalVisibility) + Ivar->getAccessControl() == ObjCIvarDecl::Protected); + if (!globalVisibility || CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden) IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); - else if (IsClassHidden(ID)) - IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); - else if (CGM.getLangOptions().getVisibilityMode() == - LangOptions::DefaultVisibility) + else IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); IvarOffsetGV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(IvarOffsetGV); @@ -5633,8 +5612,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, &CGM.getModule()); } - if (CGM.getLangOptions().getVisibilityMode() == - LangOptions::HiddenVisibility) + if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden) Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); Entry->setAlignment(8); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 7dacc3bfce..855791a5d3 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -95,54 +95,45 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg; } -/// setGlobalVisibility - Set the visibility for the given LLVM -/// GlobalValue according to the given clang AST visibility value. -static void setGlobalVisibility(llvm::GlobalValue *GV, - VisibilityAttr::VisibilityTypes Vis) { - // Internal definitions should always have default visibility. - if (GV->hasLocalLinkage()) { - GV->setVisibility(llvm::GlobalValue::DefaultVisibility); - return; +LangOptions::VisibilityMode +CodeGenModule::getDeclVisibilityMode(const Decl *D) const { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->getStorageClass() == VarDecl::PrivateExtern) + return LangOptions::Hidden; + + if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) { + switch (attr->getVisibility()) { + default: assert(0 && "Unknown visibility!"); + case VisibilityAttr::DefaultVisibility: + return LangOptions::Default; + case VisibilityAttr::HiddenVisibility: + return LangOptions::Hidden; + case VisibilityAttr::ProtectedVisibility: + return LangOptions::Protected; + } } - switch (Vis) { - default: assert(0 && "Unknown visibility!"); - case VisibilityAttr::DefaultVisibility: - GV->setVisibility(llvm::GlobalValue::DefaultVisibility); - break; - case VisibilityAttr::HiddenVisibility: - GV->setVisibility(llvm::GlobalValue::HiddenVisibility); - break; - case VisibilityAttr::ProtectedVisibility: - GV->setVisibility(llvm::GlobalValue::ProtectedVisibility); - break; - } + return getLangOptions().getVisibilityMode(); } -static void setGlobalOptionVisibility(llvm::GlobalValue *GV, - LangOptions::VisibilityMode Vis) { - // Internal definitions should always have default visibility. +void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, + const Decl *D) const { + // Internal definitions always have default visibility. if (GV->hasLocalLinkage()) { GV->setVisibility(llvm::GlobalValue::DefaultVisibility); return; } - switch (Vis) { + switch (getDeclVisibilityMode(D)) { 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; + case LangOptions::Default: + return GV->setVisibility(llvm::GlobalValue::DefaultVisibility); + case LangOptions::Hidden: + return GV->setVisibility(llvm::GlobalValue::HiddenVisibility); + case LangOptions::Protected: + return GV->setVisibility(llvm::GlobalValue::ProtectedVisibility); } } - /// \brief Retrieves the mangled name for the given declaration. /// @@ -270,25 +261,18 @@ void CodeGenModule::SetGlobalValueAttributes(const Decl *D, GV->setLinkage(llvm::Function::WeakAnyLinkage); } - // FIXME: Figure out the relative priority of the attribute, - // -fvisibility, and private_extern. if (ForDefinition) { - if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) - setGlobalVisibility(GV, attr->getVisibility()); - else - setGlobalOptionVisibility(GV, getLangOptions().getVisibilityMode()); - } + setGlobalVisibility(GV, D); - if (const SectionAttr *SA = D->getAttr<SectionAttr>()) - GV->setSection(SA->getName()); - - // Only add to llvm.used when we see a definition, otherwise we - // might add multiple times or risk the value being replaced by a - // subsequent RAUW. - if (ForDefinition) { + // Only add to llvm.used when we see a definition, otherwise we + // might add multiple times or risk the value being replaced by a + // subsequent RAUW. if (D->hasAttr<UsedAttr>()) AddUsedGlobal(GV); } + + if (const SectionAttr *SA = D->getAttr<SectionAttr>()) + GV->setSection(SA->getName()); } void CodeGenModule::SetFunctionAttributes(const Decl *D, @@ -645,7 +629,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, // FIXME: Merge with other attribute handling code. if (D->getStorageClass() == VarDecl::PrivateExtern) - setGlobalVisibility(GV, VisibilityAttr::HiddenVisibility); + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakImportAttr>()) GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); @@ -746,10 +730,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // "extern int x[];") and then a definition of a different type (e.g. // "int x[10];"). This also happens when an initializer has a different type // from the type of the global (this happens with unions). - // - // FIXME: This also ends up happening if there's a definition followed by - // a tentative definition! (Although Sema rejects that construct - // at the moment.) if (GV == 0 || GV->getType()->getElementType() != InitType || GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) { @@ -789,42 +769,20 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { GV->setLinkage(llvm::Function::DLLExportLinkage); else if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakImportAttr>()) GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage); - else { - // FIXME: This isn't right. This should handle common linkage and other - // stuff. - switch (D->getStorageClass()) { - case VarDecl::Static: assert(0 && "This case handled above"); - case VarDecl::Auto: - case VarDecl::Register: - assert(0 && "Can't have auto or register globals"); - case VarDecl::None: - if (!D->getInit() && !CompileOpts.NoCommon) - GV->setLinkage(llvm::GlobalVariable::CommonLinkage); - else - GV->setLinkage(llvm::GlobalVariable::ExternalLinkage); - break; - case VarDecl::Extern: - // FIXME: common - break; - - case VarDecl::PrivateExtern: - GV->setVisibility(llvm::GlobalValue::HiddenVisibility); - // FIXME: common - break; - } - } - - if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) - setGlobalVisibility(GV, attr->getVisibility()); + else if (!CompileOpts.NoCommon && + (!D->hasExternalStorage() && !D->getInit())) + GV->setLinkage(llvm::GlobalVariable::CommonLinkage); else - setGlobalOptionVisibility(GV, getLangOptions().getVisibilityMode()); + GV->setLinkage(llvm::GlobalVariable::ExternalLinkage); - if (const SectionAttr *SA = D->getAttr<SectionAttr>()) - GV->setSection(SA->getName()); + setGlobalVisibility(GV, D); if (D->hasAttr<UsedAttr>()) AddUsedGlobal(GV); + if (const SectionAttr *SA = D->getAttr<SectionAttr>()) + GV->setSection(SA->getName()); + // Emit global variable debug information. if (CGDebugInfo *DI = getDebugInfo()) { DI->setLocation(D->getLocation()); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index a1e2efc439..b2e6e228e0 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -14,6 +14,7 @@ #ifndef CLANG_CODEGEN_CODEGENMODULE_H #define CLANG_CODEGEN_CODEGENMODULE_H +#include "clang/Basic/LangOptions.h" #include "clang/AST/Attr.h" #include "CGBlocks.h" #include "CGCall.h" @@ -167,6 +168,13 @@ public: Diagnostic &getDiags() const { return Diags; } const llvm::TargetData &getTargetData() const { return TheTargetData; } + /// getDeclVisibilityMode - Compute the visibility of the decl \arg D. + LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const; + + /// setGlobalVisibility - Set the visibility for the given LLVM + /// GlobalValue. + void setGlobalVisibility(llvm::GlobalValue *GV, const Decl *D) const; + /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the /// given global variable. If Ty is non-null and if the global doesn't exist, /// then it will be greated with the specified type instead of whatever the |