r275737 - CodeGen: honour dllstorage on ObjC types
Saleem Abdulrasool via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 17 15:27:44 PDT 2016
Author: compnerd
Date: Sun Jul 17 17:27:44 2016
New Revision: 275737
URL: http://llvm.org/viewvc/llvm-project?rev=275737&view=rev
Log:
CodeGen: honour dllstorage on ObjC types
Add support for ObjC types to respect the DLLImport/DLLExport storage
annotations. This only effects COFF output. This would allow usage with
clang/C2, but not with clang/LLVM due to hard coded section names.
Added:
cfe/trunk/test/CodeGenObjC/dllstorage.m
Modified:
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=275737&r1=275736&r2=275737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sun Jul 17 17:27:44 2016
@@ -1073,11 +1073,44 @@ llvm::Value *CGObjCGNU::GetClassNamed(Co
// techniques can modify the name -> class mapping.
llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *OID) {
- return GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported());
+ auto *Value =
+ GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported());
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) {
+ auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
+ if (OID->hasAttr<DLLExportAttr>())
+ DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
+ else if (OID->hasAttr<DLLImportAttr>())
+ DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
+ ClassSymbol->setDLLStorageClass(DLLStorage);
+ }
+ }
+ return Value;
}
llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
- return GetClassNamed(CGF, "NSAutoreleasePool", false);
+ auto *Value = GetClassNamed(CGF, "NSAutoreleasePool", false);
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value)) {
+ IdentifierInfo &II = CGF.CGM.getContext().Idents.get("NSAutoreleasePool");
+ 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;
+
+ auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
+ if (!VD || VD->hasAttr<DLLImportAttr>())
+ DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
+ else if (VD->hasAttr<DLLExportAttr>())
+ DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
+
+ ClassSymbol->setDLLStorageClass(DLLStorage);
+ }
+ }
+ return Value;
}
llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,
@@ -2354,6 +2387,14 @@ void CGObjCGNU::GenerateClass(const ObjC
NULLPtr, NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0],
GenerateIvarList(empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr,
NULLPtr, ZeroPtr, ZeroPtr, true);
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ auto Storage = llvm::GlobalValue::DefaultStorageClass;
+ if (OID->getClassInterface()->hasAttr<DLLImportAttr>())
+ Storage = llvm::GlobalValue::DLLImportStorageClass;
+ else if (OID->getClassInterface()->hasAttr<DLLExportAttr>())
+ Storage = llvm::GlobalValue::DLLExportStorageClass;
+ cast<llvm::GlobalValue>(MetaClassStruct)->setDLLStorageClass(Storage);
+ }
// Generate the class structure
llvm::Constant *ClassStruct = GenerateClassStructure(
@@ -2361,6 +2402,14 @@ void CGObjCGNU::GenerateClass(const ObjC
llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
StrongIvarBitmap, WeakIvarBitmap);
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ auto Storage = llvm::GlobalValue::DefaultStorageClass;
+ if (OID->getClassInterface()->hasAttr<DLLImportAttr>())
+ Storage = llvm::GlobalValue::DLLImportStorageClass;
+ else if (OID->getClassInterface()->hasAttr<DLLExportAttr>())
+ Storage = llvm::GlobalValue::DLLExportStorageClass;
+ cast<llvm::GlobalValue>(ClassStruct)->setDLLStorageClass(Storage);
+ }
// Resolve the class aliases, if they exist.
if (ClassPtrAlias) {
@@ -2854,7 +2903,12 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(C
const ObjCIvarDecl *Ivar) {
if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
- if (RuntimeVersion < 10)
+
+ // The MSVC linker cannot have a single global defined as LinkOnceAnyLinkage
+ // and ExternalLinkage, so create a reference to the ivar global and rely on
+ // the definition being created as part of GenerateClass.
+ if (RuntimeVersion < 10 ||
+ CGF.CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment())
return CGF.Builder.CreateZExtOrBitCast(
CGF.Builder.CreateDefaultAlignedLoad(CGF.Builder.CreateAlignedLoad(
ObjCIvarOffsetVariable(Interface, Ivar),
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=275737&r1=275736&r2=275737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sun Jul 17 17:27:44 2016
@@ -5951,8 +5951,9 @@ llvm::GlobalVariable *CGObjCNonFragileAB
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;
}
@@ -5977,18 +5978,42 @@ void CGObjCNonFragileABIMac::GetClassSiz
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) {
if (!ObjCEmptyCacheVar) {
- ObjCEmptyCacheVar = new llvm::GlobalVariable(
- CGM.getModule(), ObjCTypes.CacheTy, false,
- llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");
+ 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.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
- ObjCEmptyVtableVar = new llvm::GlobalVariable(
- CGM.getModule(), ObjCTypes.ImpnfABITy, false,
- llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");
+ 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)?
@@ -6004,7 +6029,9 @@ void CGObjCNonFragileABIMac::GenerateCla
assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
// Build the flags for the metaclass.
- bool classIsHidden = CI->getVisibility() == HiddenVisibility;
+ bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
+ ? !CI->hasAttr<DLLExportAttr>()
+ : CI->getVisibility() == HiddenVisibility;
if (classIsHidden)
flags |= NonFragileABI_Class_Hidden;
@@ -6013,7 +6040,7 @@ void CGObjCNonFragileABIMac::GenerateCla
if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
flags |= NonFragileABI_Class_HasCXXStructors;
if (!ID->hasNonZeroConstructors())
- flags |= NonFragileABI_Class_HasCXXDestructorOnly;
+ flags |= NonFragileABI_Class_HasCXXDestructorOnly;
}
if (!CI->getSuperClass()) {
@@ -6022,9 +6049,15 @@ void CGObjCNonFragileABIMac::GenerateCla
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();
@@ -6037,11 +6070,17 @@ void CGObjCNonFragileABIMac::GenerateCla
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.
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 =
@@ -6051,6 +6090,9 @@ void CGObjCNonFragileABIMac::GenerateCla
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
@@ -6085,6 +6127,9 @@ void CGObjCNonFragileABIMac::GenerateCla
SuperClassGV =
GetClassGlobal((getClassSymbolPrefix() + SuperClassName).str(),
Super->isWeakImported());
+ if (CGM.getTriple().isOSBinFormatCOFF())
+ if (Super->hasAttr<DLLImportAttr>())
+ SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
}
GetClassSizeInfo(ID, InstanceStart, InstanceSize);
@@ -6095,6 +6140,9 @@ void CGObjCNonFragileABIMac::GenerateCla
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(CI);
@@ -6312,18 +6360,28 @@ CGObjCNonFragileABIMac::EmitMethodList(T
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;
}
@@ -6337,14 +6395,17 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVa
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;
}
@@ -7179,11 +7240,14 @@ CGObjCNonFragileABIMac::GetEHType(QualTy
// There's a particular fixed type info for 'id'.
if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
- if (!IDEHType)
+ if (!IDEHType) {
IDEHType =
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;
}
@@ -7238,11 +7302,19 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
// 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_$_" + ClassName);
+ 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.
@@ -7250,11 +7322,14 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
std::string VTableName = "objc_ehtype_vtable";
auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
- if (!VTableGV)
+ 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[] = {
@@ -7274,11 +7349,16 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
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);
+ if (!CGM.getTriple().isOSBinFormatCOFF())
+ if (ID->getVisibility() == HiddenVisibility)
+ Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
const auto &DL = CGM.getDataLayout();
Entry->setAlignment(DL.getABITypeAlignment(ObjCTypes.EHTypeTy));
Added: cfe/trunk/test/CodeGenObjC/dllstorage.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/dllstorage.m?rev=275737&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/dllstorage.m (added)
+++ cfe/trunk/test/CodeGenObjC/dllstorage.m Sun Jul 17 17:27:44 2016
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
+// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=objfw -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FW %s
+
+// CHECK-IR-DAG: @_objc_empty_cache = external dllimport global %struct._objc_cache
+
+__declspec(dllimport)
+ at interface I
++ (instancetype) new;
+ at end
+
+// CHECK-IR-DAG: @"OBJC_METACLASS_$_I" = external dllimport global %struct._class_t
+// CHECK-IR-DAG: @"OBJC_CLASS_$_I" = external dllimport global %struct._class_t
+
+__declspec(dllexport)
+ at interface J : I
+ at end
+
+// CHECK-IR-DAG: @"OBJC_METACLASS_$_J" = dllexport global %struct._class_t
+// CHECK-IR-DAG: @"OBJC_CLASS_$_J" = dllexport global %struct._class_t
+
+// CHECK-FW-DAG: @_OBJC_METACLASS_J = dllexport global
+// CHECK-FW-DAG: @_OBJC_CLASS_J = dllexport global
+
+ at implementation J {
+ id _ivar;
+}
+ at end
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_J._ivar" = global i32
+
+ at interface K : J
+ at end
+
+// CHECK-IR-DAG: @"OBJC_METACLASS_$_K" = global %struct._class_t
+// CHECK-IR-DAG: @"OBJC_CLASS_$_K" = global %struct._class_t
+
+// CHECK-FW-DAG: @_OBJC_METACLASS_K = global
+// CHECK-FW-DAG: @_OBJC_CLASS_K = global
+
+ at implementation K {
+ id _ivar;
+}
+ at end
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_K._ivar" = global i32
+
+__declspec(dllexport)
+ at interface L : K
+ at end
+
+// CHECK-IR-DAG: @"OBJC_METACLASS_$_L" = dllexport global %struct._class_t
+// CHECK-IR-DAG: @"OBJC_CLASS_$_L" = dllexport global %struct._class_t
+
+// CHECK-FW-DAG: @_OBJC_METACLASS_L = dllexport global
+// CHECK-FW-DAG: @_OBJC_CLASS_L = dllexport global
+
+ at implementation L {
+ id _none;
+
+ @public
+ id _public;
+
+ @protected
+ id _protected;
+
+ @package
+ id _package;
+
+ @private
+ id _private;
+}
+ at end
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_L._none" = global i32
+// CHECK-IR-DAG: @"OBJC_IVAR_$_L._public" = dllexport global i32
+// CHECK-IR-DAG: @"OBJC_IVAR_$_L._protected" = dllexport global i32
+// CHECK-IR-DAG: @"OBJC_IVAR_$_L._package" = global i32
+// CHECK-IR-DAG: @"OBJC_IVAR_$_L._private" = global i32
+
+__declspec(dllimport)
+ at interface M : I {
+ @public
+ id _ivar;
+}
+ at end
+
+// CHEKC-FW-DAG: @_OBJC_CLASS_M = external dllimport global i32
+
+// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
+
+__declspec(dllexport)
+__attribute__((__objc_exception__))
+ at interface N : I
+ at end
+
+// CHECK-FW-DAG: @_OBJC_METACLASS_N = dllexport global
+// CHECK-FW-DAG: @_OBJC_CLASS_N = dllexport global
+
+ at implementation N : I
+ at end
+
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_N" = dllexport global %struct._objc_typeinfo
+
+__declspec(dllimport)
+__attribute__((__objc_exception__))
+ at interface O : I
+ at end
+
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_O" = external dllimport global %struct._objc_typeinfo
+
+__attribute__((__objc_exception__))
+ at interface P : I
+ at end
+
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external global %struct._objc_typeinfo
+
+int g() {
+ @autoreleasepool {
+ M *mi = [M new];
+ @try {
+ mi->_ivar = (void *)0;
+ @throw(@"CFConstantString");
+ } @catch (id) {
+ return 1;
+ } @catch (I *) {
+ return 2;
+ } @catch (J *) {
+ return 3;
+ } @catch (K *) {
+ return 4;
+ } @catch (L *) {
+ return 5;
+ } @catch (M *) {
+ return 6;
+ } @catch (N *) {
+ return 7;
+ } @catch (O *) {
+ return 8;
+ } @catch (P *) {
+ return 9;
+ }
+ }
+ return 0;
+}
+
+// CHECK-IR-DAG: @OBJC_EHTYPE_id = external dllimport global %struct._objc_typeinfo
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_I" = weak global %struct._objc_typeinfo
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_K" = weak global %struct._objc_typeinfo
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_L" = weak global %struct._objc_typeinfo
+// CHECK-IR-DAG: @"OBJC_EHTYPE_$_M" = weak global %struct._objc_typeinfo
+
More information about the cfe-commits
mailing list