зеркало из https://github.com/microsoft/clang-1.git
Implementation definition of interfaces with __objc_exception attribute.
- Complete <rdar://problem/6635883> Support __objc_exception__ attribute git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68591 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
75c47a5cdf
Коммит
8158a2f78c
|
@ -712,7 +712,7 @@ private:
|
|||
/// FinishNonFragileABIModule - Write out global data structures at the end of
|
||||
/// processing a translation unit.
|
||||
void FinishNonFragileABIModule();
|
||||
|
||||
|
||||
llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
|
||||
unsigned InstanceStart,
|
||||
unsigned InstanceSize,
|
||||
|
@ -795,9 +795,10 @@ private:
|
|||
/// for the given selector.
|
||||
llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
|
||||
|
||||
/// GetInterfaceEHType - Get the ehtype for the given Objective-C
|
||||
/// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
|
||||
/// interface. The return value has type EHTypePtrTy.
|
||||
llvm::Value *GetInterfaceEHType(const ObjCInterfaceType *IT);
|
||||
llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
|
||||
bool ForDefinition);
|
||||
|
||||
const char *getMetaclassSymbolPrefix() const {
|
||||
return "OBJC_METACLASS_$_";
|
||||
|
@ -891,6 +892,16 @@ static llvm::Constant *getConstantGEP(llvm::Constant *C,
|
|||
return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
|
||||
}
|
||||
|
||||
/// hasObjCExceptionAttribute - Return true if this class or any super
|
||||
/// class has the __objc_exception__ attribute.
|
||||
static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) {
|
||||
if (OID->getAttr<ObjCExceptionAttr>())
|
||||
return true;
|
||||
if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
|
||||
return hasObjCExceptionAttribute(Super);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* *** CGObjCMac Public Interface *** */
|
||||
|
||||
CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
|
||||
|
@ -4238,6 +4249,10 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
|
|||
flags = CLS;
|
||||
if (classIsHidden)
|
||||
flags |= OBJC2_CLS_HIDDEN;
|
||||
|
||||
if (hasObjCExceptionAttribute(ID->getClassInterface()))
|
||||
flags |= CLS_EXCEPTION;
|
||||
|
||||
if (!ID->getClassInterface()->getSuperClass()) {
|
||||
flags |= CLS_ROOT;
|
||||
SuperClassGV = 0;
|
||||
|
@ -4287,6 +4302,10 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
|
|||
classIsHidden);
|
||||
UsedGlobals.push_back(ClassMD);
|
||||
DefinedClasses.push_back(ClassMD);
|
||||
|
||||
// Force the definition of the EHType if necessary.
|
||||
if (flags & CLS_EXCEPTION)
|
||||
GetInterfaceEHType(ID->getClassInterface(), true);
|
||||
}
|
||||
|
||||
/// GenerateProtocolRef - This routine is called to generate code for
|
||||
|
@ -5356,7 +5375,7 @@ CGObjCNonFragileABIMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
|
|||
const ObjCInterfaceType *IT =
|
||||
PT->getPointeeType()->getAsObjCInterfaceType();
|
||||
assert(IT && "Invalid @catch type.");
|
||||
llvm::Value *EHType = GetInterfaceEHType(IT);
|
||||
llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false);
|
||||
SelectorArgs.push_back(EHType);
|
||||
}
|
||||
}
|
||||
|
@ -5544,32 +5563,32 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
|
|||
CGF.Builder.ClearInsertionPoint();
|
||||
}
|
||||
|
||||
static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) {
|
||||
if (OID->getAttr<ObjCExceptionAttr>())
|
||||
return true;
|
||||
if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
|
||||
return hasObjCExceptionAttribute(Super);
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Value *
|
||||
CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) {
|
||||
const ObjCInterfaceDecl *ID = IT->getDecl();
|
||||
CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
|
||||
bool ForDefinition) {
|
||||
llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
|
||||
if (Entry)
|
||||
return Entry;
|
||||
|
||||
// If this type (or a super class) has the __objc_exception__
|
||||
// attribute, emit an external reference.
|
||||
if (hasObjCExceptionAttribute(IT->getDecl()))
|
||||
return Entry =
|
||||
new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0,
|
||||
(std::string("OBJC_EHTYPE_$_") +
|
||||
ID->getIdentifier()->getName()),
|
||||
&CGM.getModule());
|
||||
// If we don't need a definition, return the entry if found or check
|
||||
// if we use an external reference.
|
||||
if (!ForDefinition) {
|
||||
if (Entry)
|
||||
return Entry;
|
||||
|
||||
// If this type (or a super class) has the __objc_exception__
|
||||
// attribute, emit an external reference.
|
||||
if (hasObjCExceptionAttribute(ID))
|
||||
return Entry =
|
||||
new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
0,
|
||||
(std::string("OBJC_EHTYPE_$_") +
|
||||
ID->getIdentifier()->getName()),
|
||||
&CGM.getModule());
|
||||
}
|
||||
|
||||
// Otherwise we need to either make a new entry or fill in the
|
||||
// initializer.
|
||||
assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
|
||||
std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
|
||||
std::string VTableName = "objc_ehtype_vtable";
|
||||
llvm::GlobalVariable *VTableGV =
|
||||
|
@ -5587,17 +5606,28 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) {
|
|||
Values[2] = GetClassGlobal(ClassName, false);
|
||||
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
|
||||
|
||||
Entry =
|
||||
new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
|
||||
llvm::GlobalValue::WeakAnyLinkage,
|
||||
Init,
|
||||
(std::string("OBJC_EHTYPE_$_") +
|
||||
ID->getIdentifier()->getName()),
|
||||
&CGM.getModule());
|
||||
if (Entry) {
|
||||
Entry->setInitializer(Init);
|
||||
} else {
|
||||
Entry = new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
|
||||
llvm::GlobalValue::WeakAnyLinkage,
|
||||
Init,
|
||||
(std::string("OBJC_EHTYPE_$_") +
|
||||
ID->getIdentifier()->getName()),
|
||||
&CGM.getModule());
|
||||
}
|
||||
|
||||
if (CGM.getLangOptions().getVisibilityMode() ==
|
||||
LangOptions::HiddenVisibility)
|
||||
Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
Entry->setSection("__DATA,__datacoal_nt,coalesced");
|
||||
Entry->setAlignment(8);
|
||||
|
||||
if (ForDefinition) {
|
||||
Entry->setSection("__DATA,__objc_const");
|
||||
Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
||||
} else {
|
||||
Entry->setSection("__DATA,__datacoal_nt,coalesced");
|
||||
}
|
||||
|
||||
return Entry;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
// RUN: grep '@"OBJC_METACLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_CLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak global .*section "__DATA,__datacoal_nt,coalesced", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH2" = external global' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH3" = global .*section "__DATA,__objc_const", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3 &&
|
||||
// RUN: grep -F 'define internal void @"\01-[A im0]"' %t &&
|
||||
// FIXME: Should include category name.
|
||||
// RUN: grep -F 'define internal void @"\01-[A im1]"' %t &&
|
||||
|
@ -13,6 +15,8 @@
|
|||
// RUN: grep '@"OBJC_METACLASS_$_A" = hidden global .*section "__DATA, __objc_data", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_CLASS_$_A" = hidden global .*section "__DATA, __objc_data", align 8' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak hidden global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH2" = external global' %t &&
|
||||
// RUN: grep '@"OBJC_EHTYPE_$_EH3" = hidden global .*section "__DATA,__objc_const", align 8' %t &&
|
||||
// RUN: grep -F 'define internal void @"\01-[A im0]"' %t &&
|
||||
// FIXME: Should include category name.
|
||||
// RUN: grep -F 'define internal void @"\01-[A im1]"' %t &&
|
||||
|
@ -39,6 +43,10 @@ __attribute__((__objc_exception__))
|
|||
@interface EH2
|
||||
@end
|
||||
|
||||
__attribute__((__objc_exception__))
|
||||
@interface EH3
|
||||
@end
|
||||
|
||||
void f1();
|
||||
|
||||
void f0(id x) {
|
||||
|
@ -46,5 +54,9 @@ void f0(id x) {
|
|||
f1();
|
||||
} @catch (EH1 *x) {
|
||||
} @catch (EH2 *x) {
|
||||
} @catch (EH3 *x) {
|
||||
}
|
||||
}
|
||||
|
||||
@implementation EH3
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче