[cfe-commits] r68591 - in /cfe/trunk: lib/CodeGen/CGObjCMac.cpp test/CodeGenObjC/metadata_symbols.m
Daniel Dunbar
daniel at zuster.org
Tue Apr 7 21:21:03 PDT 2009
Author: ddunbar
Date: Tue Apr 7 23:21:03 2009
New Revision: 68591
URL: http://llvm.org/viewvc/llvm-project?rev=68591&view=rev
Log:
Implementation definition of interfaces with __objc_exception attribute.
- Complete <rdar://problem/6635883> Support __objc_exception__
attribute
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/test/CodeGenObjC/metadata_symbols.m
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=68591&r1=68590&r2=68591&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Apr 7 23:21:03 2009
@@ -712,7 +712,7 @@
/// 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 @@
/// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
Modified: cfe/trunk/test/CodeGenObjC/metadata_symbols.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/metadata_symbols.m?rev=68591&r1=68590&r2=68591&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/metadata_symbols.m (original)
+++ cfe/trunk/test/CodeGenObjC/metadata_symbols.m Tue Apr 7 23:21:03 2009
@@ -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 @@
@interface EH2
@end
+__attribute__((__objc_exception__))
+ at interface EH3
+ at end
+
void f1();
void f0(id x) {
@@ -46,5 +54,9 @@
f1();
} @catch (EH1 *x) {
} @catch (EH2 *x) {
+ } @catch (EH3 *x) {
}
}
+
+ at implementation EH3
+ at end
More information about the cfe-commits
mailing list