diff options
author | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
commit | 06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch) | |
tree | ab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp | |
parent | 2dd166267f53df1c3748b4325d294b9b839de74b (diff) | |
download | FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz |
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0
release, and add lld 3.9.0. Also completely revamp the build system for
clang, llvm, lldb and their related tools.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld are available here:
<http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan
Beich for their help.
Relnotes: yes
MFC r309147:
Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek):
[PPC] Set SP after loading data from stack frame, if no red zone is
present
Follow-up to r280705: Make sure that the SP is only restored after
all data is loaded from the stack frame, if there is no red zone.
This completes the fix for
https://llvm.org/bugs/show_bug.cgi?id=26519.
Differential Revision: https://reviews.llvm.org/D24466
Reported by: Mark Millard
PR: 214433
MFC r309149:
Pull in r283060 from upstream llvm trunk (by Hal Finkel):
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
This change enables soft-float for PowerPC64, and also makes
soft-float disable all vector instruction sets for both 32-bit and
64-bit modes. This latter part is necessary because the PPC backend
canonicalizes many Altivec vector types to floating-point types, and
so soft-float breaks scalarization support for many operations. Both
for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware
floating-point also disables vector instructions (embedded targets
without hardware floating point support are unlikely to have Altivec,
etc. and operating system kernels desiring not to use floating-point
registers to lower syscall cost are unlikely to want to use vector
registers either). If someone needs this to work, we'll need to
change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is
enabled, hardware floating-point support needs to be expressed as a
positive feature, like the others, and not a negative feature,
because target features cannot have dependencies on the disabling of
some other feature. So +soft-float has now become -hard-float.
Fixes PR26970.
Pull in r283061 from upstream clang trunk (by Hal Finkel):
[PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float
Enable soft-float support on PPC64, as the backend now supports it.
Also, the backend now uses -hard-float instead of +soft-float, so set
the target features accordingly.
Fixes PR26970.
Reported by: Mark Millard
PR: 214433
MFC r309212:
Add a few missed clang 3.9.0 files to OptionalObsoleteFiles.
MFC r309262:
Fix packaging for clang, lldb and lld 3.9.0
During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE
directive in the usr.bin/clang/*.mk files got dropped accidentally.
Restore it, with a few minor changes and additions:
* Correct license in clang.ucl to NCSA
* Add PACKAGE=clang for clang and most of the "ll" tools
* Put lldb in its own package
* Put lld in its own package
Reviewed by: gjb, jmallett
Differential Revision: https://reviews.freebsd.org/D8666
MFC r309656:
During the bootstrap phase, when building the minimal llvm library on
PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream
llvm revision r271821 disabled the use of std::call_once, which causes
some fallback functions from Atomic.cpp to be used instead.
Reported by: Mark Millard
PR: 214902
MFC r309835:
Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR
70528 (bogus error: constructor required before non-static data member).
This should fix buildworld with the external gcc package.
Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/
MFC r310194:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
3.9.1 release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp | 672 |
1 files changed, 409 insertions, 263 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp index e30b287..5ab9fc4 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp @@ -236,17 +236,14 @@ public: CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // id objc_getProperty (id, SEL, ptrdiff_t, bool) - SmallVector<CanQualType,4> Params; CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); - Params.push_back(IdType); - Params.push_back(SelType); - Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); - Params.push_back(Ctx.BoolTy); + CanQualType Params[] = { + IdType, SelType, + Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy}; llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo( - IdType, false, false, Params, FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(IdType, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); } @@ -254,19 +251,18 @@ public: CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) - SmallVector<CanQualType,6> Params; CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); - Params.push_back(IdType); - Params.push_back(SelType); - Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); - Params.push_back(IdType); - Params.push_back(Ctx.BoolTy); - Params.push_back(Ctx.BoolTy); + CanQualType Params[] = { + IdType, + SelType, + Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), + IdType, + Ctx.BoolTy, + Ctx.BoolTy}; llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo( - Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); } @@ -290,9 +286,8 @@ public: Params.push_back(IdType); Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified()); llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo( - Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); const char *name; if (atomic && copy) name = "objc_setProperty_atomic_copy"; @@ -317,9 +312,8 @@ public: Params.push_back(Ctx.BoolTy); Params.push_back(Ctx.BoolTy); llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo( - Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); } @@ -336,10 +330,8 @@ public: Params.push_back(Ctx.VoidPtrTy); Params.push_back(Ctx.VoidPtrTy); llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false, false, - Params, - FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic"); } @@ -350,12 +342,25 @@ public: SmallVector<CanQualType,1> Params; Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); llvm::FunctionType *FTy = - Types.GetFunctionType(Types.arrangeLLVMFunctionInfo( - Ctx.VoidTy, false, false, Params, FunctionType::ExtInfo(), - RequiredArgs::All)); + Types.GetFunctionType( + Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); } + llvm::Constant *getLookUpClassFn() { + CodeGen::CodeGenTypes &Types = CGM.getTypes(); + ASTContext &Ctx = CGM.getContext(); + // Class objc_lookUpClass (const char *) + SmallVector<CanQualType,1> Params; + Params.push_back( + Ctx.getCanonicalType(Ctx.getPointerType(Ctx.CharTy.withConst()))); + llvm::FunctionType *FTy = + Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration( + Ctx.getCanonicalType(Ctx.getObjCClassType()), + Params)); + return CGM.CreateRuntimeFunction(FTy, "objc_lookUpClass"); + } + /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. llvm::Constant *getGcReadWeakFn() { // id objc_read_weak (id *) @@ -576,7 +581,6 @@ public: return CGM.CreateRuntimeFunction( llvm::FunctionType::get(CGM.Int32Ty, params, false), "objc_exception_match"); - } /// SetJmpFn - LLVM _setjmp function. @@ -600,7 +604,6 @@ public: /// modern abi class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { public: - // MethodListnfABITy - LLVM for struct _method_list_t llvm::StructType *MethodListnfABITy; @@ -967,7 +970,8 @@ protected: llvm::Constant *EmitPropertyList(Twine Name, const Decl *Container, const ObjCContainerDecl *OCD, - const ObjCCommonTypesHelper &ObjCTypes); + const ObjCCommonTypesHelper &ObjCTypes, + bool IsClassProperty); /// EmitProtocolMethodTypes - Generate the array of extended method type /// strings. The return value has type Int8PtrPtrTy. @@ -981,13 +985,20 @@ protected: SmallVectorImpl<llvm::Constant*> &Properties, const Decl *Container, const ObjCProtocolDecl *Proto, - const ObjCCommonTypesHelper &ObjCTypes); + const ObjCCommonTypesHelper &ObjCTypes, + bool IsClassProperty); /// GetProtocolRef - Return a reference to the internal protocol /// description, creating an empty one if it has not been /// defined. The return value has type ProtocolPtrTy. llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); + /// Return a reference to the given Class using runtime calls rather than + /// by a symbol reference. + llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF, + const ObjCInterfaceDecl *ID, + ObjCCommonTypesHelper &ObjCTypes); + public: /// CreateMetadataVar - Create a global variable with internal /// linkage for use by the Objective-C runtime. @@ -1079,7 +1090,8 @@ private: /// has type ClassExtensionPtrTy. llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID, CharUnits instanceSize, - bool hasMRCWeakIvars); + bool hasMRCWeakIvars, + bool isClassProperty); /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class. @@ -1119,9 +1131,8 @@ private: /// EmitMethodList - Emit the method list for the given /// implementation. The return value has type MethodListPtrTy. - llvm::Constant *EmitMethodList(Twine Name, - const char *Section, - ArrayRef<llvm::Constant*> Methods); + llvm::Constant *EmitMethodList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods); /// EmitMethodDescList - Emit a method description list for a list of /// method declarations. @@ -1134,9 +1145,8 @@ private: /// - begin, end: The method list to output. /// /// The return value has type MethodDescriptionListPtrTy. - llvm::Constant *EmitMethodDescList(Twine Name, - const char *Section, - ArrayRef<llvm::Constant*> Methods); + llvm::Constant *EmitMethodDescList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods); /// GetOrEmitProtocol - Get the protocol object for the given /// declaration, emitting it if necessary. The return value has type @@ -1255,7 +1265,7 @@ public: /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, + llvm::GlobalVariable *GetClassGlobal(StringRef Name, bool Weak = false) override { llvm_unreachable("CGObjCMac::GetClassGlobal"); } @@ -1293,9 +1303,8 @@ private: /// AddModuleClassList - Add the given list of class pointers to the /// module with the provided symbol and section names. - void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, - const char *SymbolName, - const char *SectionName); + void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container, + StringRef SymbolName, StringRef SectionName); llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, unsigned InstanceStart, @@ -1314,9 +1323,8 @@ private: /// EmitMethodList - Emit the method list for the given /// implementation. The return value has type MethodListnfABITy. - llvm::Constant *EmitMethodList(Twine Name, - const char *Section, - ArrayRef<llvm::Constant*> Methods); + llvm::Constant *EmitMethodList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods); /// EmitIvarList - Emit the ivar list for the given /// implementation. If ForClass is true the list of class ivars /// (i.e. metaclass ivars) is emitted, otherwise the list of @@ -1357,7 +1365,7 @@ private: /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, + llvm::GlobalVariable *GetClassGlobal(StringRef Name, bool Weak = false) override; /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, @@ -1398,13 +1406,9 @@ private: llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID, bool ForDefinition); - const char *getMetaclassSymbolPrefix() const { - return "OBJC_METACLASS_$_"; - } + StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; } - const char *getClassSymbolPrefix() const { - return "OBJC_CLASS_$_"; - } + StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; } void GetClassSizeInfo(const ObjCImplementationDecl *OID, uint32_t &InstanceStart, @@ -1506,12 +1510,15 @@ public: llvm::Constant *GetSetStructFunction() override { return ObjCTypes.getCopyStructFn(); } + llvm::Constant *GetGetStructFunction() override { return ObjCTypes.getCopyStructFn(); } + llvm::Constant *GetCppAtomicObjectSetFunction() override { return ObjCTypes.getCppAtomicObjectFunction(); } + llvm::Constant *GetCppAtomicObjectGetFunction() override { return ObjCTypes.getCppAtomicObjectFunction(); } @@ -1934,7 +1941,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, // Emit a null-check if there's a consumed argument other than the receiver. bool RequiresNullCheck = false; if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) { - for (const auto *ParamDecl : Method->params()) { + for (const auto *ParamDecl : Method->parameters()) { if (ParamDecl->hasAttr<NSConsumedAttr>()) { if (!nullReturn.NullBB) nullReturn.init(CGF, Arg0); @@ -2027,6 +2034,7 @@ namespace { bool IsDisordered = false; llvm::SmallVector<IvarInfo, 8> IvarsInfo; + public: IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin, CharUnits instanceEnd, bool forStrongLayout) @@ -2062,7 +2070,7 @@ namespace { printf("\n"); } }; -} +} // end anonymous namespace llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, const CGBlockInfo &blockInfo) { @@ -2141,7 +2149,6 @@ void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) { } } - /// getBlockCaptureLifetime - This routine returns life time of the captured /// block variable for the purpose of block layout meta-data generation. FQT is /// the type of the variable captured in the block. @@ -2629,7 +2636,6 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, return getBitmapBlockLayout(false); } - llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T) { assert(CGM.getLangOpts().getGC() == LangOptions::NonGC); @@ -2677,6 +2683,25 @@ llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { return GetOrEmitProtocolRef(PD); } +llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime( + CodeGenFunction &CGF, + const ObjCInterfaceDecl *ID, + ObjCCommonTypesHelper &ObjCTypes) { + llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn(); + + llvm::Value *className = + CGF.CGM.GetAddrOfConstantCString(ID->getObjCRuntimeNameAsString()) + .getPointer(); + ASTContext &ctx = CGF.CGM.getContext(); + className = + CGF.Builder.CreateBitCast(className, + CGF.ConvertType( + ctx.getPointerType(ctx.CharTy.withConst()))); + llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className); + call->setDoesNotThrow(); + return call; +} + /* // Objective-C 1.0 extensions struct _objc_protocol { @@ -2798,6 +2823,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { struct objc_method_description_list *optional_class_methods; struct objc_property_list *instance_properties; const char ** extendedMethodTypes; + struct objc_property_list *class_properties; }; */ llvm::Constant * @@ -2816,13 +2842,16 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, "__OBJC,__cat_cls_meth,regular,no_dead_strip", OptClassMethods), EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD, - ObjCTypes), + ObjCTypes, false), EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(), - MethodTypesExt, ObjCTypes)}; + MethodTypesExt, ObjCTypes), + EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr, + PD, ObjCTypes, true)}; // Return null if no extension bits are used. if (Values[1]->isNullValue() && Values[2]->isNullValue() && - Values[3]->isNullValue() && Values[4]->isNullValue()) + Values[3]->isNullValue() && Values[4]->isNullValue() && + Values[5]->isNullValue()) return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); llvm::Constant *Init = @@ -2878,10 +2907,15 @@ PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet, SmallVectorImpl<llvm::Constant *> &Properties, const Decl *Container, const ObjCProtocolDecl *Proto, - const ObjCCommonTypesHelper &ObjCTypes) { + const ObjCCommonTypesHelper &ObjCTypes, + bool IsClassProperty) { for (const auto *P : Proto->protocols()) - PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes); + PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes, + IsClassProperty); + for (const auto *PD : Proto->properties()) { + if (IsClassProperty != PD->isClassProperty()) + continue; if (!PropertySet.insert(PD->getIdentifier()).second) continue; llvm::Constant *Prop[] = { @@ -2907,7 +2941,17 @@ PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet, llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, const Decl *Container, const ObjCContainerDecl *OCD, - const ObjCCommonTypesHelper &ObjCTypes) { + const ObjCCommonTypesHelper &ObjCTypes, + bool IsClassProperty) { + if (IsClassProperty) { + // Make this entry NULL for OS X with deployment target < 10.11, for iOS + // with deployment target < 9.0. + const llvm::Triple &Triple = CGM.getTarget().getTriple(); + if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) || + (Triple.isiOS() && Triple.isOSVersionLT(9))) + return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + } + SmallVector<llvm::Constant *, 16> Properties; llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; @@ -2919,10 +2963,15 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) for (const ObjCCategoryDecl *ClassExt : OID->known_extensions()) for (auto *PD : ClassExt->properties()) { + if (IsClassProperty != PD->isClassProperty()) + continue; PropertySet.insert(PD->getIdentifier()); AddProperty(PD); } + for (const auto *PD : OCD->properties()) { + if (IsClassProperty != PD->isClassProperty()) + continue; // Don't emit duplicate metadata for properties that were already in a // class extension. if (!PropertySet.insert(PD->getIdentifier()).second) @@ -2932,11 +2981,13 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name, if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) { for (const auto *P : OID->all_referenced_protocols()) - PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes); + PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes, + IsClassProperty); } else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) { for (const auto *P : CD->protocols()) - PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes); + PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes, + IsClassProperty); } // Return null for empty list. @@ -3001,8 +3052,8 @@ CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { } llvm::Constant * -CGObjCMac::EmitMethodDescList(Twine Name, const char *Section, - ArrayRef<llvm::Constant*> Methods) { +CGObjCMac::EmitMethodDescList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods) { // Return null for empty list. if (Methods.empty()) return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); @@ -3029,6 +3080,7 @@ CGObjCMac::EmitMethodDescList(Twine Name, const char *Section, struct _objc_protocol_list *protocols; uint32_t size; // <rdar://4585769> struct _objc_property_list *instance_properties; + struct _objc_property_list *class_properties; }; */ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { @@ -3055,7 +3107,7 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { // Class methods should always be defined. ClassMethods.push_back(GetMethodConstant(I)); - llvm::Constant *Values[7]; + llvm::Constant *Values[8]; Values[0] = GetClassName(OCD->getName()); Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString()); LazySymbols.insert(Interface->getIdentifier()); @@ -3077,9 +3129,12 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { // If there is no category @interface then there can be no properties. if (Category) { Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), - OCD, Category, ObjCTypes); + OCD, Category, ObjCTypes, false); + Values[7] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), + OCD, Category, ObjCTypes, true); } else { Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + Values[7] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); } llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, @@ -3274,7 +3329,8 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); Values[ 9] = Protocols; Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size); - Values[11] = EmitClassExtension(ID, Size, hasMRCWeak); + Values[11] = EmitClassExtension(ID, Size, hasMRCWeak, + false/*isClassProperty*/); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, Values); std::string Name("OBJC_CLASS_"); @@ -3338,8 +3394,9 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, Values[ 9] = Protocols; // ivar_layout for metaclass is always NULL. Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); - // The class extension is always unused for metaclasses. - Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); + // The class extension is used to store class properties for metaclasses. + Values[11] = EmitClassExtension(ID, CharUnits::Zero(), false/*hasMRCWeak*/, + true/*isClassProperty*/); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, Values); @@ -3413,19 +3470,28 @@ llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { */ llvm::Constant * CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID, - CharUnits InstanceSize, bool hasMRCWeakIvars) { + CharUnits InstanceSize, bool hasMRCWeakIvars, + bool isClassProperty) { uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy); llvm::Constant *Values[3]; Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); - Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize, - hasMRCWeakIvars); - Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), - ID, ID->getClassInterface(), ObjCTypes); + if (isClassProperty) { + llvm::Type *PtrTy = CGM.Int8PtrTy; + Values[1] = llvm::Constant::getNullValue(PtrTy); + } else + Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize, + hasMRCWeakIvars); + if (isClassProperty) + Values[2] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ID->getName(), + ID, ID->getClassInterface(), ObjCTypes, true); + else + Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), + ID, ID->getClassInterface(), ObjCTypes, false); // Return null if no extension bits are used. - if (Values[1]->isNullValue() && Values[2]->isNullValue()) + if ((!Values[1] || Values[1]->isNullValue()) && Values[2]->isNullValue()) return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); llvm::Constant *Init = @@ -3530,9 +3596,8 @@ llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); } -llvm::Constant *CGObjCMac::EmitMethodList(Twine Name, - const char *Section, - ArrayRef<llvm::Constant*> Methods) { +llvm::Constant *CGObjCMac::EmitMethodList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods) { // Return null for empty list. if (Methods.empty()) return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); @@ -3607,6 +3672,7 @@ llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic, llvm::Constant *CGObjCMac::GetGetStructFunction() { return ObjCTypes.getCopyStructFn(); } + llvm::Constant *CGObjCMac::GetSetStructFunction() { return ObjCTypes.getCopyStructFn(); } @@ -3614,6 +3680,7 @@ llvm::Constant *CGObjCMac::GetSetStructFunction() { llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() { return ObjCTypes.getCppAtomicObjectFunction(); } + llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() { return ObjCTypes.getCppAtomicObjectFunction(); } @@ -3711,7 +3778,7 @@ namespace { void emitWriteHazard(); void emitHazardsInNewBlocks(); }; -} +} // end anonymous namespace /// Create the fragile-ABI read and write hazards based on the current /// state of the function, which is presumed to be immediately prior @@ -4332,7 +4399,6 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *args[] = { src, dst.getPointer() }; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args, "weakassign"); - return; } /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. @@ -4358,7 +4424,6 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, else CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args, "threadlocalassign"); - return; } /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. @@ -4380,7 +4445,6 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); - return; } /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. @@ -4401,7 +4465,6 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *args[] = { src, dst.getPointer() }; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args, "strongassign"); - return; } void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, @@ -4455,7 +4518,8 @@ enum ImageInfoFlags { // A flag indicating that the module has no instances of a @synthesize of a // superclass variable. <rdar://problem/6803242> eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang. - eImageInfo_ImageIsSimulated = (1 << 5) + eImageInfo_ImageIsSimulated = (1 << 5), + eImageInfo_ClassProperties = (1 << 6) }; void CGObjCCommonMac::EmitImageInfo() { @@ -4507,6 +4571,10 @@ void CGObjCCommonMac::EmitImageInfo() { Triple.getArch() == llvm::Triple::x86_64)) Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated", eImageInfo_ImageIsSimulated); + + // Indicate whether we are generating class properties. + Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties", + eImageInfo_ClassProperties); } // struct objc_module { @@ -4602,6 +4670,11 @@ llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID) { + // If the class has the objc_runtime_visible attribute, we need to + // use the Objective-C runtime to get the class. + if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) + return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); + return EmitClassRefFromId(CGF, ID->getIdentifier()); } @@ -4954,7 +5027,7 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD, baseOffset = CharUnits::Zero(); } - baseOffset = baseOffset.RoundUpToAlignment(CGM.getPointerAlign()); + baseOffset = baseOffset.alignTo(CGM.getPointerAlign()); } else { CGM.getContext().DeepCollectObjCIvars(OI, true, ivars); @@ -5131,9 +5204,8 @@ void CGObjCMac::FinishModule() { } CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) - : CGObjCCommonMac(cgm), - ObjCTypes(cgm) { - ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr; + : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), + ObjCEmptyVtableVar(nullptr) { ObjCABI = 2; } @@ -5223,7 +5295,6 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) // struct _objc_cache * CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); CachePtrTy = llvm::PointerType::getUnqual(CacheTy); - } ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) @@ -5256,12 +5327,13 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) // struct _objc_method_description_list *optional_class_methods; // struct _objc_property_list *instance_properties; // const char ** extendedMethodTypes; + // struct _objc_property_list *class_properties; // } ProtocolExtensionTy = llvm::StructType::create("struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy, MethodDescriptionListPtrTy, PropertyListPtrTy, - Int8PtrPtrTy, nullptr); + Int8PtrPtrTy, PropertyListPtrTy, nullptr); // struct _objc_protocol_extension * ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); @@ -5359,14 +5431,17 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) // char *class_name; // struct _objc_method_list *instance_method; // struct _objc_method_list *class_method; + // struct _objc_protocol_list *protocols; // uint32_t size; // sizeof(struct _objc_category) // struct _objc_property_list *instance_properties;// category's @property + // struct _objc_property_list *class_properties; // } CategoryTy = llvm::StructType::create("struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy, MethodListPtrTy, ProtocolListPtrTy, - IntTy, PropertyListPtrTy, nullptr); + IntTy, PropertyListPtrTy, PropertyListPtrTy, + nullptr); // Global metadata structures @@ -5405,7 +5480,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) llvm::StructType::create("struct._objc_exception_data", llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize), StackPtrTy, nullptr); - } ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) @@ -5434,6 +5508,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // const uint32_t flags; // = 0 // const char ** extendedMethodTypes; // const char *demangledName; + // const struct _prop_list_t * class_properties; // } // Holder for struct _protocol_list_t * @@ -5446,7 +5521,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, - Int8PtrTy, + Int8PtrTy, PropertyListPtrTy, nullptr); // struct _protocol_t* @@ -5539,6 +5614,8 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // const struct _method_list_t * const class_methods; // const struct _protocol_list_t * const protocols; // const struct _prop_list_t * const properties; + // const struct _prop_list_t * const class_properties; + // const uint32_t size; // } CategorynfABITy = llvm::StructType::create("struct._category_t", Int8PtrTy, ClassnfABIPtrTy, @@ -5546,6 +5623,8 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, + PropertyListPtrTy, + IntTy, nullptr); // New types for nonfragile abi messaging. @@ -5609,10 +5688,9 @@ llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { return nullptr; } -void CGObjCNonFragileABIMac:: -AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container, - const char *SymbolName, - const char *SectionName) { +void CGObjCNonFragileABIMac::AddModuleClassList( + ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, + StringRef SectionName) { unsigned NumClasses = Container.size(); if (!NumClasses) @@ -5814,13 +5892,16 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( if (flags & NonFragileABI_Class_Meta) { Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes); - Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + Values[ 9] = EmitPropertyList( + "\01l_OBJC_$_CLASS_PROP_LIST_" + ID->getObjCRuntimeNameAsString(), + ID, ID->getClassInterface(), ObjCTypes, true); } else { Values[ 7] = EmitIvarList(ID); Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak); - Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(), - ID, ID->getClassInterface(), ObjCTypes); + Values[ 9] = EmitPropertyList( + "\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(), + ID, ID->getClassInterface(), ObjCTypes, false); } llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, Values); @@ -5870,8 +5951,9 @@ llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData( GV->setSection("__DATA, __objc_data"); GV->setAlignment( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)); - if (HiddenVisibility) - GV->setVisibility(llvm::GlobalValue::HiddenVisibility); + if (!CGM.getTriple().isOSBinFormatCOFF()) + if (HiddenVisibility) + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); return GV; } @@ -5896,49 +5978,60 @@ void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); } +static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, + StringRef Name) { + IdentifierInfo &II = CGM.getContext().Idents.get(Name); + TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); + DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); + + const VarDecl *VD = nullptr; + for (const auto &Result : DC->lookup(&II)) + if ((VD = dyn_cast<VarDecl>(Result))) + break; + + if (!VD) + return llvm::GlobalValue::DLLImportStorageClass; + if (VD->hasAttr<DLLExportAttr>()) + return llvm::GlobalValue::DLLExportStorageClass; + if (VD->hasAttr<DLLImportAttr>()) + return llvm::GlobalValue::DLLImportStorageClass; + return llvm::GlobalValue::DefaultStorageClass; +} + void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { - std::string ClassName = ID->getObjCRuntimeNameAsString(); if (!ObjCEmptyCacheVar) { - ObjCEmptyCacheVar = new llvm::GlobalVariable( - CGM.getModule(), - ObjCTypes.CacheTy, - false, - llvm::GlobalValue::ExternalLinkage, - nullptr, - "_objc_empty_cache"); - - // Make this entry NULL for any iOS device target, any iOS simulator target, - // OS X with deployment target 10.9 or later. + ObjCEmptyCacheVar = + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, + llvm::GlobalValue::ExternalLinkage, nullptr, + "_objc_empty_cache"); + if (CGM.getTriple().isOSBinFormatCOFF()) + ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache")); + + // Only OS X with deployment version <10.9 use the empty vtable symbol const llvm::Triple &Triple = CGM.getTarget().getTriple(); - if (Triple.isiOS() || Triple.isWatchOS() || - (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9))) - // This entry will be null. - ObjCEmptyVtableVar = nullptr; - else - ObjCEmptyVtableVar = new llvm::GlobalVariable( - CGM.getModule(), - ObjCTypes.ImpnfABITy, - false, - llvm::GlobalValue::ExternalLinkage, - nullptr, - "_objc_empty_vtable"); - } - assert(ID->getClassInterface() && - "CGObjCNonFragileABIMac::GenerateClass - class is 0"); + if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) + ObjCEmptyVtableVar = + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, + llvm::GlobalValue::ExternalLinkage, nullptr, + "_objc_empty_vtable"); + } + // FIXME: Is this correct (that meta class size is never computed)? uint32_t InstanceStart = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); uint32_t InstanceSize = InstanceStart; uint32_t flags = NonFragileABI_Class_Meta; - llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix()); - llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix()); - llvm::SmallString<64> TClassName; llvm::GlobalVariable *SuperClassGV, *IsAGV; + StringRef ClassName = ID->getObjCRuntimeNameAsString(); + const auto *CI = ID->getClassInterface(); + assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0"); + // Build the flags for the metaclass. - bool classIsHidden = - ID->getClassInterface()->getVisibility() == HiddenVisibility; + bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF()) + ? !CI->hasAttr<DLLExportAttr>() + : CI->getVisibility() == HiddenVisibility; if (classIsHidden) flags |= NonFragileABI_Class_Hidden; @@ -5947,45 +6040,59 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { if (ID->hasNonZeroConstructors() || ID->hasDestructors()) { flags |= NonFragileABI_Class_HasCXXStructors; if (!ID->hasNonZeroConstructors()) - flags |= NonFragileABI_Class_HasCXXDestructorOnly; + flags |= NonFragileABI_Class_HasCXXDestructorOnly; } - if (!ID->getClassInterface()->getSuperClass()) { + if (!CI->getSuperClass()) { // class is root flags |= NonFragileABI_Class_Root; - TClassName = ObjCClassName; - TClassName += ClassName; - SuperClassGV = GetClassGlobal(TClassName.str(), - ID->getClassInterface()->isWeakImported()); - TClassName = ObjCMetaClassName; - TClassName += ClassName; - IsAGV = GetClassGlobal(TClassName.str(), - ID->getClassInterface()->isWeakImported()); + + SuperClassGV = GetClassGlobal((getClassSymbolPrefix() + ClassName).str(), + CI->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (CI->hasAttr<DLLImportAttr>()) + SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + + IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + ClassName).str(), + CI->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (CI->hasAttr<DLLImportAttr>()) + IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); } else { // Has a root. Current class is not a root. const ObjCInterfaceDecl *Root = ID->getClassInterface(); while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) Root = Super; - TClassName = ObjCMetaClassName ; - TClassName += Root->getObjCRuntimeNameAsString(); - IsAGV = GetClassGlobal(TClassName.str(), + + const auto *Super = CI->getSuperClass(); + StringRef RootClassName = Root->getObjCRuntimeNameAsString(); + StringRef SuperClassName = Super->getObjCRuntimeNameAsString(); + + IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + RootClassName).str(), Root->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (Root->hasAttr<DLLImportAttr>()) + IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); // work on super class metadata symbol. - TClassName = ObjCMetaClassName; - TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); - SuperClassGV = GetClassGlobal( - TClassName.str(), - ID->getClassInterface()->getSuperClass()->isWeakImported()); - } - llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, - InstanceStart, - InstanceSize,ID); - TClassName = ObjCMetaClassName; - TClassName += ClassName; - llvm::GlobalVariable *MetaTClass = BuildClassMetaData( - TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden, - ID->getClassInterface()->isWeakImported()); + SuperClassGV = + GetClassGlobal((getMetaclassSymbolPrefix() + SuperClassName).str(), + Super->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (Super->hasAttr<DLLImportAttr>()) + SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + } + + llvm::GlobalVariable *CLASS_RO_GV = + BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID); + + llvm::GlobalVariable *MetaTClass = + BuildClassMetaData((getMetaclassSymbolPrefix() + ClassName).str(), IsAGV, + SuperClassGV, CLASS_RO_GV, classIsHidden, + CI->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (CI->hasAttr<DLLExportAttr>()) + MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); DefinedMetaClasses.push_back(MetaTClass); // Metadata for the class @@ -6006,34 +6113,38 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { flags |= NonFragileABI_Class_HasCXXDestructorOnly; } - if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) + if (hasObjCExceptionAttribute(CGM.getContext(), CI)) flags |= NonFragileABI_Class_Exception; - if (!ID->getClassInterface()->getSuperClass()) { + if (!CI->getSuperClass()) { flags |= NonFragileABI_Class_Root; SuperClassGV = nullptr; } else { // Has a root. Current class is not a root. - TClassName = ObjCClassName; - TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); - SuperClassGV = GetClassGlobal( - TClassName.str(), - ID->getClassInterface()->getSuperClass()->isWeakImported()); + const auto *Super = CI->getSuperClass(); + StringRef SuperClassName = Super->getObjCRuntimeNameAsString(); + + SuperClassGV = + GetClassGlobal((getClassSymbolPrefix() + SuperClassName).str(), + Super->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (Super->hasAttr<DLLImportAttr>()) + SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); } + GetClassSizeInfo(ID, InstanceStart, InstanceSize); - CLASS_RO_GV = BuildClassRoTInitializer(flags, - InstanceStart, - InstanceSize, - ID); + CLASS_RO_GV = + BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID); - TClassName = ObjCClassName; - TClassName += ClassName; llvm::GlobalVariable *ClassMD = - BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV, - classIsHidden, - ID->getClassInterface()->isWeakImported()); + BuildClassMetaData((getClassSymbolPrefix() + ClassName).str(), MetaTClass, + SuperClassGV, CLASS_RO_GV, classIsHidden, + CI->isWeakImported()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (CI->hasAttr<DLLExportAttr>()) + ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); DefinedClasses.push_back(ClassMD); - ImplementedClasses.push_back(ID->getClassInterface()); + ImplementedClasses.push_back(CI); // Determine if this class is also "non-lazy". if (ImplementationIsNonLazy(ID)) @@ -6041,7 +6152,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { // Force the definition of the EHType if necessary. if (flags & NonFragileABI_Class_Exception) - GetInterfaceEHType(ID->getClassInterface(), true); + GetInterfaceEHType(CI, true); // Make sure method definition entries are all clear for next implementation. MethodDefinitions.clear(); } @@ -6093,6 +6204,8 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF, /// const struct _method_list_t * const class_methods; /// const struct _protocol_list_t * const protocols; /// const struct _prop_list_t * const properties; +/// const struct _prop_list_t * const class_properties; +/// const uint32_t size; /// } /// void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { @@ -6107,7 +6220,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { llvm::SmallString<64> ExtClassName(getClassSymbolPrefix()); ExtClassName += Interface->getObjCRuntimeNameAsString(); - llvm::Constant *Values[6]; + llvm::Constant *Values[8]; Values[0] = GetClassName(OCD->getIdentifier()->getName()); // meta-class entry symbol llvm::GlobalVariable *ClassGV = @@ -6156,12 +6269,18 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { Category->protocol_begin(), Category->protocol_end()); Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), - OCD, Category, ObjCTypes); + OCD, Category, ObjCTypes, false); + Values[6] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), + OCD, Category, ObjCTypes, true); } else { Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); } + unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy); + Values[7] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); + llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, Values); @@ -6210,9 +6329,8 @@ llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( /// } /// llvm::Constant * -CGObjCNonFragileABIMac::EmitMethodList(Twine Name, - const char *Section, - ArrayRef<llvm::Constant*> Methods) { +CGObjCNonFragileABIMac::EmitMethodList(Twine Name, StringRef Section, + ArrayRef<llvm::Constant *> Methods) { // Return null for empty list. if (Methods.empty()) return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); @@ -6242,18 +6360,28 @@ CGObjCNonFragileABIMac::EmitMethodList(Twine Name, llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar) { - const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); llvm::SmallString<64> Name("OBJC_IVAR_$_"); Name += Container->getObjCRuntimeNameAsString(); Name += "."; Name += Ivar->getName(); - llvm::GlobalVariable *IvarOffsetGV = - CGM.getModule().getGlobalVariable(Name); - if (!IvarOffsetGV) - IvarOffsetGV = new llvm::GlobalVariable( - CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false, - llvm::GlobalValue::ExternalLinkage, nullptr, Name.str()); + llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); + if (!IvarOffsetGV) { + IvarOffsetGV = + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy, + false, llvm::GlobalValue::ExternalLinkage, + nullptr, Name.str()); + if (CGM.getTriple().isOSBinFormatCOFF()) { + bool IsPrivateOrPackage = + Ivar->getAccessControl() == ObjCIvarDecl::Private || + Ivar->getAccessControl() == ObjCIvarDecl::Package; + + if (ID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage) + IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + else if (ID->hasAttr<DLLImportAttr>()) + IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + } + } return IvarOffsetGV; } @@ -6267,14 +6395,17 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, IvarOffsetGV->setAlignment( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy)); - // FIXME: This matches gcc, but shouldn't the visibility be set on the use as - // well (i.e., in ObjCIvarOffsetVariable). - if (Ivar->getAccessControl() == ObjCIvarDecl::Private || - Ivar->getAccessControl() == ObjCIvarDecl::Package || - ID->getVisibility() == HiddenVisibility) - IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); - else - IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); + if (!CGM.getTriple().isOSBinFormatCOFF()) { + // FIXME: This matches gcc, but shouldn't the visibility be set on the use + // as well (i.e., in ObjCIvarOffsetVariable). + if (Ivar->getAccessControl() == ObjCIvarDecl::Private || + Ivar->getAccessControl() == ObjCIvarDecl::Package || + ID->getVisibility() == HiddenVisibility) + IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); + else + IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); + } + IvarOffsetGV->setSection("__DATA, __objc_ivar"); return IvarOffsetGV; } @@ -6361,7 +6492,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( const ObjCProtocolDecl *PD) { llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; - if (!Entry) { + if (!Entry) // We use the initializer as a marker of whether this is a forward // reference or not. At module finalization we add the empty // contents for protocols which were referenced but never defined. @@ -6370,8 +6501,6 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( false, llvm::GlobalValue::ExternalLinkage, nullptr, "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString()); - Entry->setSection("__DATA,__datacoal_nt,coalesced"); - } return Entry; } @@ -6391,6 +6520,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( /// const uint32_t flags; // = 0 /// const char ** extendedMethodTypes; /// const char *demangledName; +/// const struct _prop_list_t * class_properties; /// } /// @endcode /// @@ -6442,7 +6572,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( MethodTypesExt.insert(MethodTypesExt.end(), OptMethodTypesExt.begin(), OptMethodTypesExt.end()); - llvm::Constant *Values[12]; + llvm::Constant *Values[13]; // isa is NULL Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); Values[1] = GetClassName(PD->getObjCRuntimeNameAsString()); @@ -6466,8 +6596,9 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( + PD->getObjCRuntimeNameAsString(), "__DATA, __objc_const", OptClassMethods); - Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(), - nullptr, PD, ObjCTypes); + Values[7] = EmitPropertyList( + "\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(), + nullptr, PD, ObjCTypes, false); uint32_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); @@ -6477,6 +6608,10 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( MethodTypesExt, ObjCTypes); // const char *demangledName; Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + + Values[12] = EmitPropertyList( + "\01l_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(), + nullptr, PD, ObjCTypes, true); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, Values); @@ -6492,7 +6627,6 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString()); Entry->setAlignment( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy)); - Entry->setSection("__DATA,__datacoal_nt,coalesced"); Protocols[PD->getIdentifier()] = Entry; } @@ -6640,7 +6774,7 @@ static void appendSelectorForMessageRefTable(std::string &buffer, } } -/// Emit a "v-table" message send. We emit a weak hidden-visibility +/// Emit a "vtable" message send. We emit a weak hidden-visibility /// struct, initially containing the selector pointer and a pointer to /// a "fixup" variant of the appropriate objc_msgSend. To call, we /// load and call the function pointer, passing the address of the @@ -6734,7 +6868,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, bool requiresnullCheck = false; if (CGM.getLangOpts().ObjCAutoRefCount && method) - for (const auto *ParamDecl : method->params()) { + for (const auto *ParamDecl : method->parameters()) { if (ParamDecl->hasAttr<NSConsumedAttr>()) { if (!nullReturn.NullBB) nullReturn.init(CGF, arg0); @@ -6783,7 +6917,7 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, } llvm::GlobalVariable * -CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) { +CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name, bool Weak) { llvm::GlobalValue::LinkageTypes L = Weak ? llvm::GlobalValue::ExternalWeakLinkage : llvm::GlobalValue::ExternalLinkage; @@ -6806,9 +6940,8 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, llvm::GlobalVariable *&Entry = ClassReferences[II]; if (!Entry) { - std::string ClassName( - getClassSymbolPrefix() + - (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str()); + StringRef Name = ID ? ID->getObjCRuntimeNameAsString() : II->getName(); + std::string ClassName = (getClassSymbolPrefix() + Name).str(); llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, @@ -6822,6 +6955,11 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID) { + // If the class has the objc_runtime_visible attribute, we need to + // use the Objective-C runtime to get the class. + if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) + return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); + return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID); } @@ -7100,27 +7238,28 @@ CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, llvm::Constant * CGObjCNonFragileABIMac::GetEHType(QualType T) { // There's a particular fixed type info for 'id'. - if (T->isObjCIdType() || - T->isObjCQualifiedIdType()) { - llvm::Constant *IDEHType = - CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); - if (!IDEHType) + if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { + auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); + if (!IDEHType) { IDEHType = - new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, - false, - llvm::GlobalValue::ExternalLinkage, - nullptr, "OBJC_EHTYPE_id"); + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, + llvm::GlobalValue::ExternalLinkage, nullptr, + "OBJC_EHTYPE_id"); + if (CGM.getTriple().isOSBinFormatCOFF()) + IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id")); + } return IDEHType; } // All other types should be Objective-C interface pointer types. - const ObjCObjectPointerType *PT = - T->getAs<ObjCObjectPointerType>(); + const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); assert(PT && "Invalid @catch type."); + const ObjCInterfaceType *IT = PT->getInterfaceType(); assert(IT && "Invalid @catch type."); + return GetInterfaceEHType(IT->getDecl(), false); -} +} void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S) { @@ -7153,6 +7292,7 @@ llvm::Constant * CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, bool ForDefinition) { llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; + StringRef ClassName = ID->getObjCRuntimeNameAsString(); // If we don't need a definition, return the entry if found or check // if we use an external reference. @@ -7162,38 +7302,43 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, // If this type (or a super class) has the __objc_exception__ // attribute, emit an external reference. - if (hasObjCExceptionAttribute(CGM.getContext(), ID)) - return Entry = - new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, - llvm::GlobalValue::ExternalLinkage, - nullptr, - ("OBJC_EHTYPE_$_" + - ID->getObjCRuntimeNameAsString())); + if (hasObjCExceptionAttribute(CGM.getContext(), ID)) { + std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str(); + Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, + false, llvm::GlobalValue::ExternalLinkage, + nullptr, EHTypeName); + if (CGM.getTriple().isOSBinFormatCOFF()) { + if (ID->hasAttr<DLLExportAttr>()) + Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + else if (ID->hasAttr<DLLImportAttr>()) + Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + } + return Entry; + } } - // Otherwise we need to either make a new entry or fill in the - // initializer. + // Otherwise we need to either make a new entry or fill in the initializer. assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); - llvm::SmallString<64> ClassName(getClassSymbolPrefix()); - ClassName += ID->getObjCRuntimeNameAsString(); + std::string VTableName = "objc_ehtype_vtable"; - llvm::GlobalVariable *VTableGV = - CGM.getModule().getGlobalVariable(VTableName); - if (!VTableGV) - VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, - false, - llvm::GlobalValue::ExternalLinkage, - nullptr, VTableName); + auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); + if (!VTableGV) { + VTableGV = + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, + llvm::GlobalValue::ExternalLinkage, nullptr, + VTableName); + if (CGM.getTriple().isOSBinFormatCOFF()) + VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); + } llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); - llvm::Constant *Values[] = { llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV, VTableIdx), GetClassName(ID->getObjCRuntimeNameAsString()), - GetClassGlobal(ClassName.str())}; - llvm::Constant *Init = - llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); + GetClassGlobal((getClassSymbolPrefix() + ClassName).str()), + }; + llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); llvm::GlobalValue::LinkageTypes L = ForDefinition ? llvm::GlobalValue::ExternalLinkage @@ -7201,24 +7346,25 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, if (Entry) { Entry->setInitializer(Init); } else { - llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_"); - EHTYPEName += ID->getObjCRuntimeNameAsString(); - Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, - L, - Init, - EHTYPEName.str()); + Entry = + new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, L, + Init, ("OBJC_EHTYPE_$_" + ClassName).str()); + if (CGM.getTriple().isOSBinFormatCOFF()) + if (hasObjCExceptionAttribute(CGM.getContext(), ID)) + if (ID->hasAttr<DLLExportAttr>()) + Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); } assert(Entry->getLinkage() == L); - if (ID->getVisibility() == HiddenVisibility) - Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); - Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment( - ObjCTypes.EHTypeTy)); + if (!CGM.getTriple().isOSBinFormatCOFF()) + if (ID->getVisibility() == HiddenVisibility) + Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); + + const auto &DL = CGM.getDataLayout(); + Entry->setAlignment(DL.getABITypeAlignment(ObjCTypes.EHTypeTy)); if (ForDefinition) Entry->setSection("__DATA,__objc_const"); - else - Entry->setSection("__DATA,__datacoal_nt,coalesced"); return Entry; } |